Yes
No
/******************************************************************************** * 算法原理:Tarjan算法是基于对图深度优先搜索的算法, * 每个强连通分量为搜索树中的一棵子树。搜索时,把当前搜索树中未处理的节点加入一个堆栈, * 回溯时可以判断栈顶到栈中的节点是否为一个强连通分量。 * 定义:定义DFN(u)为节点u搜索的次序编号(时间戳),Low(u)为u或u的子树能够追溯到 * 的最早的栈中节点的次序号。 * 结论:当DFN(u)=Low(u)时,以u为根的搜索子树上所有节点是一个强连通分量。 * Low(u)=Min * { * DFN(u), * Low(v),(u,v)为树枝边,u为v的父节点 * DFN(v),(u,v)为指向栈中节点的后向边(非横叉边) * } * * 备注:tarjan模板题 * Problem:HDU1269迷宫城堡 * author:crazy_石头 * date: 2013/09/07 *********************************************************************************/ #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> #define A system("pause") using namespace std; const int maxn=10000+5; struct Node { int v,next; }edge[maxn*10]; int dfn[maxn],low[maxn]; bool instack[maxn]; int stack[maxn]; int head[maxn]; int top,Bcnt,index; int cnt; int n,m; void addedge(int u,int v) { edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++; } void tarjan(int u) { int v; dfn[u]=low[u]=++index; instack[u]=true; stack[++top]=u; for(int i=head[u];~i;i=edge[i].next)//枚举每条边; { v=edge[i].v;//找到其邻接点; if(!dfn[v])//该点未访问过,则访问该点; { tarjan(v); low[u]=min(low[u],low[v]);//树边; } else if(instack[u]) { low[u]=min(dfn[v],low[u]);//后向边; } } if(dfn[u]==low[u]) { Bcnt++; do { v=stack[top--]; instack[v]=false; }while(v!=u); } } void solve() { int i; top=index=Bcnt=0; memset(instack,0,sizeof(instack)); memset(dfn,0,sizeof(dfn)); for(i=1;i<=n;i++) { if(!dfn[i]) tarjan(i); } if(Bcnt==1) puts("Yes"); else puts("No"); } int main() { while(scanf("%d%d%*c",&n,&m)!=EOF) { if(n==0&&m==0) break; cnt=0; memset(head,-1,sizeof(head)); for(int i=0;i<m;i++) { int a,b; scanf("%d%d",&a,&b); addedge(a,b); } solve(); } return 0; } /*PS:刚开始一直样例WA是因为tarjan(i)写成了tarjan[i],最近老是犯二。。。。感谢byvoid大牛!*/