标签: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 }
标签:mem 就是 情况 模板 put 程序 optimize head break
原文地址:https://www.cnblogs.com/stelayuri/p/12234842.html