POJ 1236 Tarjan縮點+統計出入度
阿新 • • 發佈:2020-11-28
毫無理由地獻上證明:(其實就是Tarjan縮點以後做)
https://blog.csdn.net/tomandjake_/article/details/81842963
#include<iostream> #include<string.h> #define N 150 using namespace std; int dfn[N],low[N],id[N],a[N][N],n,past[N],pl,cnt,sum; bool vis[N],pre[N],suf[N]; void tarjan(int x) { dfn[x]=low[x]=++sum; past[++pl]=x; for (int i=1;i<=n;i++) if (!vis[i]&&a[x][i]>0){ if (low[i]==0x3f3f3f3f)tarjan(i); low[x]=(low[x]<low[i])?low[x]:low[i]; } if (low[x]==dfn[x]){ ++cnt; do{ int now=past[pl]; id[now]=cnt; } while (past[pl--]!=x); } vis[x]=true; } void trans() { memset(pre,false,sizeof(pre));memset(suf,false,sizeof(suf)); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (id[i]!=id[j]&&a[i][j])pre[id[j]]=true,suf[id[i]]=true; } int main() { cin>>n; memset(a,0,sizeof(a)); for (int i=1;i<=n;i++){ int v; while (true){ cin>>v; if (v==0)break; a[i][v]=1; } } memset(dfn,0,sizeof(dfn));memset(low,0x3f,sizeof(low));memset(vis,false,sizeof(vis)); cnt=0,sum=0;pl=0; for (int i=1;i<=n;i++) if (!vis[i])tarjan(i); if (cnt==1){cout<<"1\n0\n";return 0;} trans(); int sum1=0,sum2=0; for (int i=1;i<=cnt;i++){ if (!pre[i])sum1++; if (!suf[i])sum2++; } cout<<sum1<<"\n"<<((sum1>sum2)?sum1:sum2)<<"\n"; return 0; }