码迷,mamicode.com
首页 > 其他好文 > 详细

ZJNU 1269 - 灯塔——高级

时间:2020-01-26 22:30:13      阅读:82      评论:0      收藏:0      [点我收藏+]

标签:mem   就是   情况   模板   put   程序   optimize   head   break   

根据题目输入可以得到一个有向图

信号可以根据有向图的传递性传递,因此可以说是找到这个有向图的所有父亲即可

但又要考虑可能会出现环这类情况

所以跑一遍强连通分量模板,再根据分块后的图找到入度为0的块,把这些块当作信号发出源,就可以使全图都能够收到信号

所以答案就是入度为0的块的数量

(因为跑完程序刚好卡了时间限制,所以使用了缓冲区读入优化,最终程序耗时78ms)

 1 /*
 2 Written By StelaYuri
 3 */
 4 #pragma GCC optimize(3)
 5 #include<bits/stdc++.h>
 6 using namespace std;
 7 const int N=100005;
 8 vector<int> G[N];
 9 stack<int> S;
10 int pre[N],lowlink[N],sccno[N],dfs_clock,scc_cnt,ind[N];
11 const int bsz=1<<16;
12 char bf[bsz],*head,*tail;
13 inline char gc(){
14     if(head==tail){
15         int l=fread(bf,1,bsz,stdin);
16         tail=(head=bf)+l;
17     }
18     return *head++;
19 }
20 inline int read(){
21     int x=0;char c=gc();
22     while(!isdigit(c))c=gc();
23     for(;isdigit(c);c=gc())x=x*10+c-0;
24     return x;
25 }
26 inline void write(int x){
27     if(x>=10)write(x/10);
28     putchar(x%10+0);
29 }
30 void dfs(int in){
31     pre[in]=lowlink[in]=++dfs_clock;
32     S.push(in);
33     int num=G[in].size();
34     for(int i=0;i<num;i++){
35         int v=G[in][i];
36         if(!pre[v]){
37             dfs(v);
38             lowlink[in]=min(lowlink[in],lowlink[v]);
39         }
40         else if(!sccno[v])
41             lowlink[in]=min(lowlink[in],pre[v]);
42     }
43     if(lowlink[in]==pre[in]){
44         scc_cnt++;
45         while(1){
46             int x=S.top();
47             S.pop();
48             sccno[x]=scc_cnt;
49             if(x==in)
50                 break;
51         }
52     }
53 }
54 int main(){
55     int N=read(),M=read(),i,j,a,b;
56     for(i=0;i<M;i++){
57         a=read();
58         b=read();
59         G[a].push_back(b);
60     }
61     dfs_clock=scc_cnt=0;
62     memset(sccno,0,sizeof sccno);
63     memset(pre,0,sizeof pre);
64     for(i=1;i<=N;i++)
65         if(!pre[i])
66             dfs(i);
67     memset(ind,0,sizeof ind);
68     for(i=1;i<=N;i++){
69         a=G[i].size();
70         for(j=0;j<a;j++)
71             if(sccno[i]!=sccno[G[i][j]])
72                 ind[sccno[G[i][j]]]++;
73     }
74     for(a=0,i=1;i<=scc_cnt;i++)
75         if(!ind[i])
76             a++;
77     write(a);
78     
79     return 0;
80 }

 

ZJNU 1269 - 灯塔——高级

标签:mem   就是   情况   模板   put   程序   optimize   head   break   

原文地址:https://www.cnblogs.com/stelayuri/p/12234842.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!