zoukankan      html  css  js  c++  java
  • POJ 2553 The Bottom of a Graph

    题意:在有向图G中,给这样一个新的定义:对于在G中任何一个点v可达的点w,w都可达v,那么点v是一个sink。G图的bottom子图是由G图中所有的sink点构成,请按照顺序输出G图对应的bottom子图中的所有点编号,如果没有sink点,那么输出一个空行。
     
    题目分析:先将题目的强联通分量求出来缩成点,然后判断连通分量出度为0点 分量。

     

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    usingnamespace std;
    #define INF 0x7ffffff
    #define maxn 5005
    typedef longlong LL;
    #define Min(a,b) (a<b?a:b)
    #define MOD 1000000007
    int m, n, Time, top, ans;
    int Stack[maxn], dfn[maxn], low[maxn], blocks[maxn], Out[maxn];
    bool InStack[maxn];
    vector<vector<int> > G;
    void init()
    {
        memset(Out, 0, sizeof(Out));
        memset(dfn, 0, sizeof(dfn));
        memset(low, 0, sizeof(low));
        ans = Time = top = 0;
        G.clear();
        G.resize(n+2);
    }
    void Tarjan(int u)
    {
        dfn[u] = low[u] = ++Time;
        Stack[top++] = u;
        InStack[u] = true;
        int len = G[u].size(), v;
    
        for(int i=0; i<len; i++)
        {
            v = G[u][i];
            if( !low[v] )
            {
                Tarjan(v);
                low[u] = min(low[u], low[v]);
            }
            elseif( InStack[v] )
                low[u] = min(low[u], dfn[v]);
        }
        if(low[u] == dfn[u])
        {
            do
            {
                v  = Stack[--top];
                InStack[v] = false;
                blocks[v] = ans;
            }
            while(u != v);
            ans ++;
        }
    }
    
    void solve()
    {
        for(int i=1; i<=n; i++)
        {
            if(!low[i])
                Tarjan(i);
        }
    
        for(int i=1; i<=n; i++)
        {
            int len = G[i].size(), v;
            for(int j=0; j<len; j++)
            {
                v = G[i][j];
                if(blocks[i] != blocks[v])
                    Out[blocks[i]]  ++;
            }
        }
    
        int flag = 0;
    
        for(int i=1; i<=n; i++)
        {
            if(Out[blocks[i]] == 0 && !flag)
            {
                flag ++;
                printf("%d", i);
            }
            elseif(Out[blocks[i]] == 0)
                printf(" %d", i);
        }
        printf("
    ");
    }
    
    int main()
    {
        while(scanf("%d",&n), n)
        {
            scanf("%d",&m);
            init();
            while(m --)
            {
                int a, b;
                scanf("%d %d",&a, &b);
                G[a].push_back(b);
            }
            solve();
        }
        return0;
    }
  • 相关阅读:
    送走2015,迎来2016
    Android-Volley网络通信框架(StringRequest &amp; JsonObjectRequest)
    Mac上配置 Ruby on Rails和Git
    学习Javascript闭包(Closure)
    cocos2d-x 学习资源整理(持续更新...)
    android自己定义刷新类控件
    awk条件语句
    Leetcode 236 Lowest Common Ancestor of a Binary Tree
    Linux查看当前正在执行的进程
    Thinking in UML 学习笔记(三)——UML核心视图之类图
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4718761.html
Copyright © 2011-2022 走看看