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;
    }
  • 相关阅读:
    LINQ 详解
    oracle下查询的sql已经超出IIS响应时间
    IOC应用之 Ninject
    JSONP ---------跨域
    国内各大互联网公司相关技术站点2.0版 (集合腾讯、阿里、百度、搜狐、新浪、360等共49个)
    IO多路复用,以socket为例
    socket机制下实现的多用户与服务器交互
    在一个进程中定义多个线程
    基于tcp的socketserver,即tcp的多线程
    基于upd的socketserver,即udp的多线程
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4718761.html
Copyright © 2011-2022 走看看