强连通图缩点——cf999E

问题转换成缩点求度数为0的点的个数,s点所在联通块作额外处理

 

缩点写的很烂调了一早上。。

#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define maxn 5005
vector<int>G[maxn];

int n,m,s;

int low[maxn],dfn[maxn],ind,stk[maxn],top,ins[maxn],c[maxn],cnt;
void Tarjan(int x){
    dfn[x]=low[x]=++ind;
    stk[++top]=x;ins[x]=1;
    for(int i=0;i<G[x].size();i++){
        int y=G[x][i];
        if(!dfn[y]){
            Tarjan(y);
            low[x]=min(low[x],low[y]);
        }
        else if(ins[y])
            low[x]=min(low[x],low[y]);
    }
    if(low[x]==dfn[x]){
        cnt++;int y;
        do{
            y=stk[top--];
            ins[y]=0;
            c[y]=cnt;
        }while(x!=y);
    }
}

int main(){
    cin>>n>>m>>s;
    for(int i=1;i<=m;i++){
        int u,v;
        cin>>u>>v;
        G[u].push_back(v); 
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            Tarjan(i);
    
    //缩点重建
    int in[maxn]={}; 
    in[c[s]]++;
    
    for(int u=1;u<=n;u++){
        for(int i=0;i<G[u].size();i++)
            if(c[u]!=c[G[u][i]])
                in[c[G[u][i]]]++;
    } 
    int ans=0;
    for(int i=1;i<=cnt;i++)
        if(in[i]==0)ans++;
    cout<<ans<<'\n';
} 

 

posted on 2019-06-29 11:48  zsben  阅读(302)  评论(0编辑  收藏  举报

导航