The Bottom of a Graph POJ

来源:互联网 发布:炉石大数据各数据意义 编辑:程序博客网 时间:2024/05/16 10:34

强联通分量中出度为零的点集

题意
使用的图论的方式说明了一个新的定义,汇点的定义,v是图中的一个顶点,对于图中的每一个v能到达的顶点w,w也可达v,则称v为汇点。图的底部为图中顶点的子集,子集中的所有的点都是汇点,求图的底部。
思路
如果图的底部都是汇点,则说明底部中的任意两点都互相可达,则底部为强连通分量,并且没有出边,所以任务就变成求图的强连通分量并且出度为零的点集
代码

/* * Author       :  Echo * Email        :  1666424499@qq.com   * Description  :    * Created Time :  2017/10/15 17:54:39 * Last Modify  :  2017/10/15 18:13:03 * File Name    :  write.cpp */#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <string>using namespace std;const int maxn=1e4;const int maxm=1e6;const int INF=1e9;struct edge {    int to,next;}an[maxm];int head[maxn];int dfn[maxn]; //入栈时间戳int ins[maxn]; //是否入栈int low[maxn]; //最早发现时间int stk[maxn]; //手工栈int dot[maxn]; //缩点int out[maxn]; //出度int m=0;//edge int cntm;int top;//stackint cnt;//dotint n;//pointint tm;//timevoid addedge(int u,int v){    an[++cntm].to=v;    an[cntm].next=head[u];    head[u]=cntm;}void tarjan(int u){    dfn[u]=low[u]=++tm;    stk[++top]=u;    ins[u]=1;    for(int i=head[u];i!=-1;i=an[i].next){        int v=an[i].to;        if(dfn[v]==0){            tarjan(v);            if(low[u]>low[v]) low[u]=low[v];        }         else if(ins[v]&&low[u]>low[v]){            low[u]=low[v];        }    }    if(low[u]!=dfn[u]) return;    int v=stk[top--];    ins[v]=0;    dot[v]=++cnt;    while(u!=v){        v=stk[top--];        ins[v]=0;        dot[v]=cnt;    }}int main(){    while(~scanf("%d",&n)){        if(n==0)break;        scanf("%d",&m);        top=cnt=tm=0;        for(int i=1;i<=n;i++){            dfn[i]=ins[i]=out[i]=0;            head[i]=-1;        }        for(int i=1;i<=m;i++){            int u,v;            scanf("%d%d",&u,&v);            addedge(u,v);        }        for(int i=1;i<=n;i++){            if(dfn[i]) continue;             tarjan(i);        }        for(int u=1;u<=n;u++){            for(int i=head[u];i!=-1;i=an[i].next){                int v=an[i].to;                if(dot[u]==dot[v])continue;                out[dot[u]]++;            }        }        top=0;        for(int i=1;i<=n;i++){            if(out[dot[i]]) continue;            stk[++top]=i;        }        for(int i=1;i<=top;i++){            printf("%d%c",stk[i],i!=top? ' ':'\n');        }    }    return 0;}
原创粉丝点击