poj 2553 The Bottom of a Graph

http://poj.org/problem?id=2553

题意:给一个无向图,如果一个点v能够到达w并且w也能到v则w和v都称为一个sink,题目要求从大到小输出图中所有的sink点。注意叶子结点都是sink点。

思路:正如上面说的叶子结点都是sink,而且只有叶子结点才能形成sink点。因而先进行缩点,然后再求叶子结点。

View Code
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<bitset>
#include<string>
#include<climits>
#include<cstdio>
#include<vector>
#include<utility>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define IN puts("in")
#define OUT puts("out")
#define FR(x) freopen(x,"r",stdin)
#define FW(x) freopen(x,"w",stdout)
#define MSET(x,y) memset(x,y,sizeof(x))
#define ST system("pause")
using namespace std;

const int maxn = 5005;
struct nd
{
        int u,v,next;
}edge[maxn*100];
int head[maxn],vis[maxn],st[maxn],dfn[maxn],low[maxn],belong[maxn],out[maxn],c[maxn];
int ecnt,cnt,idx,tp;
void add(int u,int v)
{
        edge[ecnt].u = u;
        edge[ecnt].v = v;
        edge[ecnt].next = head[u];
        head[u] = ecnt++;
}
void tarjan(int u)
{
        int i,v;
        dfn[u] = low[u] = ++idx;
        st[++tp] = u;
        vis[u] = 1;
        for(i = head[u]; i != -1; i = edge[i].next)
        {
                v = edge[i].v;
                if(!dfn[v]){
                        tarjan(v);
                        low[u] = min(low[v],low[u]);
                }else if(vis[v]) low[u] = min(dfn[v],low[u]);
        }
        if(dfn[u] == low[u])
        {
                cnt++;
                do{
                        v = st[tp--];
                        vis[v] = 0;
                        belong[v] = cnt;
                }while(v!=u);
        }
}
void processing()
{
        int i,j,k,n,m,u,v;
        while(scanf("%d",&n)==1)
        {
                if(!n)return ;
                scanf("%d",&m);
                MSET(vis,0);
                MSET(dfn,0);
                MSET(belong,0);
                MSET(out,0);
                MSET(head,-1);
                ecnt = cnt = idx = tp = 0;
                for(i = 0; i < m; ++ i)
                {
                        scanf("%d %d",&u,&v);
                        add(u,v);
                }
                for(i = 1; i <= n; ++ i)
                        if(!dfn[i]) tarjan(i);
                for(i = 0; i < m; ++ i)
                {
                        u = belong[edge[i].u];
                        v = belong[edge[i].v];
                        if(u!=v)out[u]++;
                }
                k = 0;
                for(i = 1; i <= n; ++ i){j = belong[i]; if(!out[j]) c[k++] = i;}
                for(i = 0; i < k - 1; ++ i) printf("%d ",c[i]);printf("%d\n",c[i]);
        }
}
int main()
{
        processing();
        return 0;
}

 

 

posted on 2012-07-03 21:51  aigoruan  阅读(114)  评论(0)    收藏  举报

导航