POJ 2186

来源:互联网 发布:走出帝制在淘宝怎么搜 编辑:程序博客网 时间:2024/06/06 01:11

 

大致思路:算出有多少个强连通分量,再进行缩点处理再判断出度为零的缩点是否唯一#include<string.h>#include<stdio.h>#include<iostream>#include<vector>#include<stack>#include<algorithm>using namespace std;#define M 10005vector<int> G[M];//二维邻接表int n,m;//点数 边数int index;//时间戳int ncolor;//颜色的数量,即强连通分量的个数int dfn[M],low[M];int color[M];//每个点的颜色int Outdegree[M];//缩点的出度bool instack[M];//是否在栈内的标志stack<int> st;void Tarjan(int u){    int i;    if(dfn[u]!=0)        return ;    dfn[u]=low[u]=index++;    st.push(u);    instack[u]=true;    for(i=0;i<G[u].size();i++)    {        int v=G[u][i];        if(!dfn[v])        {            Tarjan(v);            if(low[u]>low[v])                low[u]=low[v];        }        else if(instack[v]==true&&low[u]>dfn[v])            low[u]=dfn[v];    }    if(dfn[u]==low[u])    {        int v;        ncolor++;        do{            v=st.top();            st.pop();            color[v]=ncolor;            instack[v]=false;        }while(u!=v);    }}void solve(){        int nzeronum=0;    int zerocolor=0;    int i,j,v,num=0;    if(ncolor==1)    {         printf("%d\n",n);         return;    }    memset(Outdegree,0,sizeof(Outdegree));    for(i=1;i<=n;i++)    {                if(Outdegree[color[i]])            continue;        for(j=0;j<G[i].size();j++)        {            v=G[i][j];            if(color[i]!=color[v])                Outdegree[color[i]]=1;        }    }    for(i=1;i<=ncolor;i++)        if(Outdegree[i]==0)        {            nzeronum++;            zerocolor=i;            if(nzeronum>1)                break;        }    if(nzeronum>1)    {            printf("0\n");        return;    }    for(i=1;i<=n;i++)        if(color[i]==zerocolor)            num++;    printf("%d\n",num);    return;}int main(){    int i,j;    //freopen("C:\\Users\\y460\\Desktop\\stdout.txt","w",stdout);    scanf("%d%d",&n,&m);    for(i=0;i<m;i++)    {        int a,b;        scanf("%d%d",&a,&b);        G[a].push_back(b);    }    memset(dfn,0,sizeof(dfn));    memset(color,0,sizeof(color));    memset(instack,false,sizeof(instack));    index=1;    ncolor=0;    for(i=1;i<=n;i++)        Tarjan(i);    solve();    //scanf("%d",&i);    return 0;}