[洛谷2002]消息扩散
Posted skylee的OI博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[洛谷2002]消息扩散相关的知识,希望对你有一定的参考价值。
思路:
Tarjan缩点后统计入度为$0$的连通分量。
1 #include<stack> 2 #include<cstdio> 3 #include<cctype> 4 #include<vector> 5 inline int getint() { 6 char ch; 7 while(!isdigit(ch=getchar())); 8 int x=ch^‘0‘; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^‘0‘); 10 return x; 11 } 12 const int V=100001; 13 std::vector<int> e[V]; 14 inline void add_edge(const int u,const int v) { 15 e[u].push_back(v); 16 } 17 int dfn[V]={0},low[V]={0},scc[V]={0},cnt=0,id=0; 18 bool ins[V]={0}; 19 std::stack<int> s; 20 void Tarjan(const int x) { 21 dfn[x]=low[x]=++cnt; 22 s.push(x); 23 ins[x]=true; 24 for(unsigned i=0;i<e[x].size();i++) { 25 int &y=e[x][i]; 26 if(!dfn[y]) { 27 Tarjan(y); 28 low[x]=std::min(low[x],low[y]); 29 } 30 else if(ins[y]) { 31 low[x]=std::min(low[x],dfn[y]); 32 } 33 } 34 if(dfn[x]==low[x]) { 35 int y; 36 ++id; 37 do { 38 y=s.top(); 39 s.pop(); 40 ins[y]=false; 41 scc[y]=id; 42 } while(y!=x); 43 } 44 } 45 int in[V]={0}; 46 int main() { 47 int n=getint(); 48 for(int m=getint();m;m--) { 49 int u=getint(),v=getint(); 50 add_edge(u,v); 51 } 52 for(int i=1;i<=n;i++) { 53 if(!dfn[i]) Tarjan(i); 54 } 55 for(int x=1;x<=n;x++) { 56 for(unsigned i=0;i<e[x].size();i++) { 57 int &y=e[x][i]; 58 if(scc[x]!=scc[y]) { 59 in[scc[y]]++; 60 } 61 } 62 } 63 int ans=0; 64 for(int i=1;i<=id;i++) { 65 if(!in[i]) ans++; 66 } 67 printf("%d\n",ans); 68 return 0; 69 }
以上是关于[洛谷2002]消息扩散的主要内容,如果未能解决你的问题,请参考以下文章