[HAOI2006]受欢迎的牛(缩点+Tarjan)

xiaoxiao2021-02-28  48

题目:

我是超链接

题解:

缩点之后求出度为0的点有几个,如果是1就输出强连通分量中点的个数,否则输出0

这个空间不知道怎么回事,点数必须开50000...........

代码:

#include <cstdio> #include <cstring> #include <iostream> #define M 50005 #define N 50005 using namespace std; int nxt[M*2],point[M*2],v[M*2],tot,tmp,n,m,NN,num; int dfn[N],low[N],strack[N],bb[N],x[N],y[N],out[N],belong[N]; bool vis[N]; 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]=++NN; vis[now]=1; strack[++tmp]=now; 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]) { ++num; int big=0; while (strack[tmp]!=now) { belong[strack[tmp]]=num; vis[strack[tmp]]=0;tmp--; big++; } belong[strack[tmp]]=num; vis[strack[tmp]]=0;tmp--;big++; bb[num]=big; } } int main() { int i,ans=0,cnt; scanf("%d%d",&n,&m); for (i=1;i<=m;i++) { scanf("%d%d",&x[i],&y[i]); addline(x[i],y[i]); } for (i=1;i<=n;i++) if (!dfn[i]) tarjan(i); for (i=1;i<=m;i++) if (belong[x[i]]!=belong[y[i]]) ++out[belong[x[i]]]; for(i=1;i<=num;i++) if (!out[i]) ans++,cnt=bb[i]; if (ans==1) printf("%d",cnt); else printf("0"); }

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

最新回复(0)