连通图(强连通分支)
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<iostream> #include<algorithm> #include<vector> using namespace std; #define maxn 10010 vector<vector<int> >G; int low[maxn],dfn[maxn],Stack[maxn],ans,sum,Time,top,n,m;//low表示搜索时间,dfn表示深度,Stack表示栈; bool vis[maxn];//标记其元素是否入栈; void Init() { G.clear(); G.resize(n+1); memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(Stack,0,sizeof(Stack)); memset(vis,false,sizeof(vis)); ans = sum = top = 0; Time = 1; } void Tarjan(int u) { int i; low[u]=dfn[u]=Time++; vis[u]=true; Stack[top++]=u; int len=G[u].size(),v; for(i=0; i<len; i++) { v=G[u][i]; if(!dfn[v]) { Tarjan(v); low[u] = min(low[u],low[v]);//如果v点可到达,那么u点也可到达 } else if(vis[v]) low[u] = min(low[u],dfn[v]);//如果某一点可到的点在栈中,构成强连通分量 } if(low[u] == dfn[u]) { do { ans++; v=Stack[--top]; vis[v]=false; } while(u!=v); sum++; } } void solve() { Tarjan(1); if(ans==n && sum==1) puts("Yes"); else puts("No"); } int main() { int a,b; while(scanf("%d%d",&n,&m),n+m) { Init(); while(m--) { scanf("%d%d",&a,&b); G[a].push_back(b); } solve(); } return 0; }