AcWing367 学校网络(tarjan)

tarjan缩点的模板题

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int id[N];
int h[N],ne[N],w[N],e[N],idx;
stack<int> q;
int scnt;
int cnt[N];
int times;
int n,m;
int dfn[N],low[N];
int ins[N];
int in[N];
int out[N];
void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void tarjan(int u){
    dfn[u]=low[u]=++times;
    q.push(u);
    ins[u]=1;
    int i;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(!dfn[j]){
            tarjan(j);
            low[u]=min(low[u],low[j]);
        }
        else if(ins[j]){
            low[u]=min(low[u],dfn[j]);
        }
    }
    if(dfn[u]==low[u]){
        ++scnt;
        while(1){
            int t=q.top();
            q.pop(),ins[t]=0;
            id[t]=scnt;
            cnt[scnt]++;
            if(t==u)
            break;
        }
    }
}
int main(){
    int i;
    cin>>n;
    memset(h,-1,sizeof h);
    for(i=1;i<=n;i++){
        int x;
        while(cin>>x,x){
            add(i,x);
        }
    }
    for(i=1;i<=n;i++){
        if(!dfn[i])
            tarjan(i);
    }
    int j;
    for(i=1;i<=n;i++){
        for(j=h[i];j!=-1;j=ne[j]){
            int k=e[j];
            if(id[i]!=id[k]){
                in[id[i]]++;
                out[id[k]]++;
            }
        }
    }
    int zero=0;
    int sign=0;
    for(i=1;i<=scnt;i++){
        if(!in[i]){
            zero++;
        }
        if(!out[i]){
            sign++;
        }
    }
    cout<<sign<<endl;
    if(scnt==1)
    cout<<0<<endl;
    else
    cout<<max(zero,sign)<<endl;
}
View Code

 

posted @ 2020-05-22 10:47  朝暮不思  阅读(158)  评论(0编辑  收藏  举报