zoukankan      html  css  js  c++  java
  • POJ 2762 Going from u to v or from v to u?(强联通 + TopSort)

    题目大意:

    为了锻炼自己的儿子 Jiajia 和Wind 把自己的儿子带入到一个洞穴内,洞穴有n个房间,洞穴的道路是单向的。
    每一次Wind 选择两个房间  x 和 y,   让他的儿子从一个房间走到另一个房间,(要么从 x->y  或者 y->x), Wind承诺这个是一定可以走到的。但是他不知道如何判断这个 xy一定是互通的,现在给你一个洞穴,问随机给你两个洞穴的编号,是否是相通的。
    题目分析:题目意思有点偏移,其实意思是(只要能从x->y  或者 y->x 这个都算是通的), 求一下TopSort,判断能否直接连成一串。
    (集训前恶补了一下数据结构,再写TopSort的时候拿以前笔记,看一下就懂了了。)
     
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <vector>
    usingnamespace std;
    #define INF 0x7ffffff
    #define maxn 1005
    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], P[maxn][maxn], blocks[maxn], In[maxn];
    bool InStack[maxn];
    vector<vector<int> > G;
    void init()
    {
        memset(In, 0, sizeof(In));
        memset(dfn, 0, sizeof(dfn));
        memset(low, 0, sizeof(low));
        memset(P, 0, sizeof(P));
        ans = Time = top = 0;
        G.clear();
        G.resize(n+2);
    }
    bool TopSort()
    {
        int cnt = 0;
        top = 0;
        for(int i=0; i<ans; i++)
        {
            if(In[i] == 0)
            {
                Stack[top ++] = i;
                cnt ++;
                break;
            }
        }
    
        while(top)
        {
            int v = Stack[--top];
            for(int i=0; i<ans; i++)
            {
                if(P[v][i] && ! --In[i])
                {
                    Stack[top++] = i;
                    cnt ++;
                }
            }
        }
        return cnt == ans;
    }
    
    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])
                {
                    int a = blocks[i], b = blocks[v];
                    P[a][b] ++;
                    if(P[a][b] == 1)
                    {
                        In[b] ++;
                        break;
                    }
    
                }
            }
        }
        if( !TopSort() )
            printf("No
    ");
        else
            puts("Yes");
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d %d",&n, &m);
            init();
            while(m --)
            {
                int a, b;
                scanf("%d %d",&a, &b);
                G[a].push_back(b);
            }
            solve();
        }
        return0;
    }
  • 相关阅读:
    影响stm32仿真的因素
    DMA 如何查看它有没有传输完成 传输完成再开启
    keil出错总结
    一个例子讲解wav头文件 stm32声音程序 录音和播放 wav
    前期绑定 vs 后期绑定
    抽象类 VS 接口 (3)
    抽象类 VS 接口(1)
    封装之--JAVA中的访问修饰符(区别于.NET)
    【DP专题】——洛谷P1156垃圾陷阱
    MySql
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4718756.html
Copyright © 2011-2022 走看看