【POJ1236】Network of Schools(Tarjan缩点)

来源:互联网 发布:知乎 资产比例 编辑:程序博客网 时间:2024/05/22 07:26

题目:

我是超链接

题意:

Q1:求入度为0的强连通分量的个数

Q2:入度为0的强连通分量的个数 与 出度为0的强连通分量的个数取max(这里记得特判num=1的情况)

代码:

#include <cstdio>#include <iostream>#include <cstring>#define M 1000005#define N 100005using 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));}


1 0
原创粉丝点击