题目:
我是超链接
题意:
Q1:求入度为0的强连通分量的个数
Q2:入度为0的强连通分量的个数 与 出度为0的强连通分量的个数取max(这里记得特判num=1的情况)
代码:
#include <cstdio> #include <iostream> #include <cstring> #define M 1000005 #define N 100005 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],in[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++; while (strack[tmp]!=now) { belong[strack[tmp]]=num; vis[strack[tmp]]=0; tmp--; } belong[strack[tmp]]=num; vis[strack[tmp]]=0; tmp--; } } int main() { int n,i,s,m=0,inn=0,outt=0; scanf("%d",&n); for (i=1;i<=n;i++) { scanf("%d",&s); while (s!=0) { x[++m]=i; y[m]=s; addline(x[m],y[m]); scanf("%d",&s); } } for (i=1;i<=n;i++) if (!dfn[i]) tarjan(i); for (i=1;i<=m;i++) if (belong[x[i]]!=belong[y[i]]) ++in[belong[y[i]]],++out[belong[x[i]]]; for (i=1;i<=num;i++) { if (!in[i]) inn++; if (!out[i]) outt++; } if (num==1) printf("1\n0"); else printf("%d\n%d",inn,max(inn,outt)); }