poj 2553

来源:互联网 发布:C语言温度转换题目 编辑:程序博客网 时间:2024/05/16 07:14

戳戳戳

题意:
如果一个点 v 能够到达 的所有点 都可以 返回来 到达 v 则称 v 是一个sink点

求 所有的 sink点

思路:
求出度 为 1 的 强连通分量 的 点
tarjan();

然后 没了 看代码

#include<cstdio>#include<algorithm>#include<cstring>using namespace std;//by mars_chint n,m,tot;int dfn[5005],low[5005],stack[5005],belong[5005],out[5005],instack[5005];int time,top,index;struct data{    int f,t,nxt;}e[5005*5005];int first[5005],ans[5005];void add(int a,int b){    e[++tot].f=a;    e[tot].t=b;    e[tot].nxt=first[a];    first[a]=tot;}void tarjan(int x){    dfn[x]=low[x]=++time;    stack[++top]=x;    instack[x]=1;    for(int i=first[x];i!=-1;i=e[i].nxt)    {        int v=e[i].t;        if(!dfn[v])        {            tarjan(v);            low[x]=min(low[x],low[v]);        }        else if(instack[v])        {            low[x]=min(low[x],dfn[v]);        }    }    if(low[x] == dfn[x])    {        ++index;        while(1)        {            int t=stack[top--];            instack[t]=0;            belong[t]=index;            if(t == x) break;        }    }}int main(){    while(scanf("%d%d",&n,&m) && n!=0)    {        tot=0,time=0,top=0,index=0;        memset(first,-1,sizeof(first));        memset(low,0,sizeof(low));        memset(dfn,0,sizeof(dfn));        memset(out,0,sizeof(out));        memset(stack,0,sizeof(stack));        for(int i=1;i<=m;i++)        {            int a,b;            scanf("%d%d",&a,&b);            add(a,b);        }        for(int i=1;i<=n;i++)        {            if(!dfn[i]) tarjan(i);        }        for(int i=1;i<=n;i++)        {            for(int j=first[i];j!=-1;j=e[j].nxt)            {                if(belong[i]!=belong[e[j].t])                {                    out[belong[i]]++;                }            }        }        int len=0;        for(int i=1;i<=n;i++)        {            if(!out[belong[i]])            {                ans[++len]=i;            }        }        for(int i=1;i<=len;i++)        {            printf("%d ",ans[i]);        }        puts("");    }}
0 0