[HDU1269]迷宫城堡(Tarjan)

xiaoxiao2021-02-28  109

题目:

我是超链接

题解:

就是个模板题啊

按理说应该有两种方法:

1、Kobalabala :从任意一个点开始,如果可以遍历到所有点,而且,反置边之后依然可以遍历到所有点那就是Yes 否则就是No(但这个方法蜜汁不对?)

2、Tarjan..........

代码:

#include <cstdio> #include <cstring> #include <iostream> using namespace std; int tot,N,tmp,cnt,strack[10005],point[100005],nxt[200005],v[200005],Dfn[10005],Low[10005]; bool vis[10005]; void cl() { tot=0; memset(point,0,sizeof(point)); memset(v,0,sizeof(v)); memset(nxt,0,sizeof(nxt)); memset(Dfn,0,sizeof(Dfn)); memset(Low,0,sizeof(Low)); tmp=0; cnt=0; } void addline(int x,int y) { ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; } void tarjan(int now) { Dfn[now]=Low[now]=++N; strack[++tmp]=now; vis[now]=1; for (int i=point[now];i;i=nxt[i]) if (!Dfn[v[i]]) { tarjan(v[i]); Low[now]=min(Low[now],Low[v[i]]); } else if (vis[v[i]]) Low[now]=min(Low[now],Dfn[v[i]]); if (Low[now]==Dfn[now]) { ++cnt; while (strack[tmp]!=now) vis[strack[tmp]]=0,tmp--; vis[strack[tmp]]=0; tmp--; } } int main() { int n,m,x,y; while (~scanf("%d%d",&n,&m)){ if (!n&&!m) return 0; cl(); for (int i=1;i<=m;++i) scanf("%d%d",&x,&y),addline(x,y); for (int i=1;i<=n;++i) if (!Dfn[i]) tarjan(i); if (cnt==1) printf("Yes\n"); else printf("No\n"); } }

转载请注明原文地址: https://www.6miu.com/read-60712.html

最新回复(0)