[POJ1236]Network of Schools(Tarjan缩点+强连通分量)

来源:互联网 发布:淘宝天猫商城 编辑:程序博客网 时间:2024/05/24 01:46

题目描述

传送门

题解

Q1:求入度为0的强连通分量的个数;
Q2:入度为0的强连通分量的个数与出度为0的强连通分量的个数取max
Q2注意特判cnt为1的情况。

代码

#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int max_n=105;int n,x,N,calc,cnt,temp,ans1,ans2;int Dfn[max_n],Low[max_n],vis[max_n],strack[max_n],belong[max_n],in[max_n],out[max_n];bool a[max_n][max_n];inline void tarjan(int now){    Dfn[now]=Low[now]=++N; vis[now]=1; strack[++temp]=now;    for (int i=1;i<=n;++i)      if (a[now][i]){        if (!Dfn[i]){            tarjan(i);            Low[now]=min(Low[now],Low[i]);        }        else if (vis[i]) Low[now]=min(Low[now],Dfn[i]);      }    if (Dfn[now]==Low[now]){        ++cnt;        while (strack[temp]!=now) belong[strack[temp]]=cnt,vis[strack[temp]]=0,temp--;        belong[strack[temp]]=cnt,vis[strack[temp]]=0,temp--;    }}int main(){    scanf("%d",&n);    for (int i=1;i<=n;++i){        while (~scanf("%d",&x)){            if (!x) break;            if (i!=x) a[i][x]=true;        }    }    for (int i=1;i<=n;++i)      if (!Dfn[i]) tarjan(i);    for (int i=1;i<=n;++i)      for (int j=1;j<=n;++j)        if (a[i][j]&&belong[i]!=belong[j]) out[belong[i]]++,in[belong[j]]++;    for (int i=1;i<=cnt;++i){        if (in[i]==0) ans1++;        if (out[i]==0) ans2++;    }    if (cnt==1) printf("1\n0\n");    else{        printf("%d\n",ans1);        printf("%d\n",max(ans1,ans2));    }}
0 0