• poj2186 Popular Cows(强连通)


    崇拜有传递性。求所有牛都崇拜的牛
    tarjan算法求强连通。

    如果不连通就不存在。如果联通,缩点后唯一一个出度为零的点就是答案,有多个则不存在。

    #include <vector>
    #include <list>
    #include <map>
    #include <set>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <bitset>
    #include <algorithm>
    #include <functional>
    #include <numeric>
    #include <utility>
    #include <complex>
    #include <sstream>
    #include <iostream>
    #include <iomanip>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    #include <cstring>
    #include <ctime>
    #include <cassert>
    using namespace std;
    
    const int N = 10005;
    const int M = 100005;
    
    struct Edge {
        int to, next;
    } edge[M];
    int head[N];
    int cnt_edge;
    
    void add_edge(int u, int v)
    {
        edge[cnt_edge].to = v;
        edge[cnt_edge].next = head[u];
        head[u] = cnt_edge;
        cnt_edge++;
    }
    
    int dfn[N];
    int low[N];
    int stk[N];
    bool in[N];
    int kind[N];
    
    int top;
    int idx;
    int cnt;
    
    int n, m;
    
    void dfs(int u)
    {
        dfn[u] = low[u] = ++idx;
        in[u] = true;
        stk[++top] = u;
        for (int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].to;
            if (!dfn[v])
            {
                dfs(v);
                low[u] = min(low[v], low[u]);
            }
            else if(in[v])
            {
                low[u] = min(low[u], dfn[v]);
            }
        }
    
        if (low[u] == dfn[u])
        {
            ++cnt;
            int j;
            do {
                j = stk[top--];
                in[j] = false;
                kind[j] = cnt;
            } while (j != u);
        }
    }
    
    void init()
    {
        memset(dfn, 0, sizeof dfn);
        memset(head, -1, sizeof head);
        cnt_edge = 0;
        top = cnt = idx = 0;
    }
    
    
    int deg[N];
    
    void solve()
    {
        // 缩点后出度为0的点个数为1
        for (int u = 1; u <= n; ++u)
        {
            int k = kind[u];
            for (int i = head[u]; i != -1; i = edge[i].next)
            {
                int v = edge[i].to;
                if (kind[u] != kind[v]) deg[k]++;
            }
        }
    
        int flag = 0;
        int p;
        for (int i = 1; i <= cnt; ++i)
        {
            if (deg[i] == 0)
            {
                flag++;
                p = i;
                if (flag > 1) break;
            }
        }
        if (flag == 1)
        {
            int ans = 0;
            for (int i = 1; i <= n; ++i) if (kind[i] == p) ++ans;
            printf("%d
    ", ans);
        }
        else
        {
            printf("0
    ");
        }
    }
    
    int main()
    {
        while (~scanf("%d%d", &n, &m))
        {
            if (n == 0 && m == 0) break;
            int a, b;
            init();
            for (int i = 0; i < m; ++i)
            {
                scanf("%d%d", &a, &b);
                add_edge(a, b);
            }
    
            for (int i = 1; i <= n; ++i)
            {
                if (!dfn[i]) dfs(i);
            }
    
            solve();
        }
        return 0;
    }
    

      

  • 相关阅读:
    P2015 二叉苹果树(树形DP)
    Treats for the Cows (区间DP)
    You Are the One(区间DP 好题)
    Palindrome subsequence (区间DP)
    Cutting Sticks(区间DP)
    L2-013 红色警报 (dfs判断图连通性)
    L2-001 紧急救援 (dijkstra+dfs回溯路径)
    多线程 -- JMM、volatile关键字、内存屏障、happens-before原则、缓存一致性
    多线程 -- 各种锁的概念
    Spring Boot 学习笔记(十六)启动原理、运行流程、自动配置原理
  • 原文地址:https://www.cnblogs.com/wenruo/p/5007977.html
Copyright © 2020-2023  润新知