题意:求一张图的强连通分量,若为1,则输出yes,否则输出no。
解题关键:targin算法模板题。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 typedef long long ll; 9 #define MAXN 10010 10 #define MAXM 100010 11 struct edge{ 12 int to,nxt; 13 }e[MAXM]; 14 15 int head[MAXN],st[MAXN],dfn[MAXN],lowest[MAXN],belong[MAXN]; 16 bool inst[MAXN]; 17 int n,m,scnt,top,tot; 18 void init(){ 19 memset(head,-1,sizeof head); 20 memset(dfn, 0, sizeof dfn); 21 scnt=top=tot=0; 22 } 23 24 void add_edge(int u, int v){ 25 e[tot].to=v; 26 e[tot].nxt=head[u]; 27 head[u]=tot++; 28 } 29 30 void Tarjan(int u){ 31 dfn[u]=lowest[u]=++tot; 32 inst[u]=1; 33 st[top++]=u; 34 for(int i=head[u];i!=-1;i=e[i].nxt){ 35 int v=e[i].to; 36 if(!dfn[v]){ 37 Tarjan(v); 38 lowest[u]=min(lowest[u],lowest[v]); 39 } 40 else if(inst[v]){ 41 lowest[u]=min(lowest[u],dfn[v]);//也可用lowest 42 } 43 } 44 if(dfn[u]==lowest[u]){ 45 scnt++; 46 int t; 47 do{ 48 t=st[--top]; 49 inst[t]=false; 50 belong[t]=scnt; 51 }while(t!=u); 52 } 53 } 54 55 inline int read(){ 56 char k=0;char ls;ls=getchar();for(;ls<'0'||ls>'9';k=ls,ls=getchar()); 57 int x=0;for(;ls>='0'&&ls<='9';ls=getchar())x=(x<<3)+(x<<1)+ls-'0'; 58 if(k=='-')x=0-x;return x; 59 } 60 61 62 void solve(){ 63 for(int i=1;i<=n;i++) 64 if(!dfn[i]) 65 Tarjan(i); 66 } 67 68 int main(){ 69 int a,b; 70 while(scanf("%d%d",&n,&m)&&(n||m)){ 71 init(); 72 while(m--){ 73 a=read(),b=read(); 74 add_edge(a,b); 75 } 76 solve(); 77 if(scnt==1) printf("Yes "); 78 else printf("No "); 79 } 80 return 0; 81 }