大意:问图中是不是所有两点都是任意可达的,i到j,同样j也要到达i.
就是缩成一个点即可,所以只需要判断scc是不是1即可。不需要找麻烦看度数。
#include<map> #include<queue> #include<cmath> #include<cstdio> #include<stack> #include<iostream> #include<cstring> #include<algorithm> #define LL int #define inf 0x3f3f3f3f #define eps 1e-8 #include<vector> #define ls l,mid,rt<<1 #define rs mid+1,r,rt<<1|1 using namespace std; const int Ma = 10100; struct node{ int to,w,next; }q[Ma*15]; int head[Ma*15],dfn[Ma],num[Ma],du[Ma],stk[Ma],vis[Ma],low[Ma]; int cnt,top,tim,scc,out[Ma]; bool bj; void Add(int a,int b){ q[cnt].to = b; q[cnt].next = head[a]; head[a] = cnt++; } void init(){ scc = cnt = top = 0; tim = 1;bj = false; memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(num,0,sizeof(num)); memset(out,0,sizeof(out)); memset(vis,0,sizeof(vis)); memset(low,0,sizeof(low)); } void Tarjan(int u){ low[u] = dfn[u] = tim++; vis[u] = 1; stk[top++] = u; for(int i = head[u]; ~i ; i = q[i].next){ int v = q[i].to; if(!vis[v]){ Tarjan(v); low[u] = min(low[u],low[v]); } else low[u] = min(low[u],dfn[v]); } if(low[u] == dfn[u]){ scc++; while( top>0&&stk[top] != u ){ top--; vis[stk[top] ] = 2; num[stk[top] ] = scc; } } } int main(){ int n,m,i,j,k,a,b,cla; while(~scanf("%d%d",&n,&m)){ if(!n&&!m) break; init(); for(i = 0;i <m;++ i){ scanf("%d%d",&a,&b); Add(a,b); } for(i = 1;i <= n;++i) if(!dfn[i]) Tarjan(i); if(scc==1) puts("Yes"); else puts("No"); } return 0; }