• poj 1236 Network of Schools 【Tarjan】


    题目链接:http://poj.org/problem?id=1236

    题意:

    本题为有向图。
    需解决两个问题:
    1 须要给多少个点,才干传遍全部点。


    2 加多少条边,使得整个图变得强连通。
    使用Tarjan进行缩点,得到一个SCC图、
    这个图有多少个入度为0的,多少个出度为0的。
    如果有n个入度为0,m个出度为0
    那么第一个答案就是n,第二个答案是max(n,m)
    代码:

    #include <stdio.h>
    #include <iostream>
    #include <math.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <algorithm>
    #include <vector>
    #include <string.h>
    #include <string>
    #include <queue>
    #include <stack>
    #include <set>
    #include <map>
    #include <sstream>
    #include <time.h>
    
    using namespace std;
    
    const int MAXN = 20010;
    const int MAXM = 50010;
    
    struct Edge
    {
        int to, next;
    }edge[MAXM];
    
    int head[MAXM], tot;
    int Low[MAXN], Dfn[MAXN], Stack[MAXN], Belong[MAXN];//Belong的值为 1 ~ scc
    int Index, top;
    int scc;//强连通个数
    bool Instack[MAXN];
    int num[MAXN];//各个强连通包括的点的个数
    
    void addedge(int u, int v)
    {
        edge[tot].to = v;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    
    void Tarjan(int u)
    {
        int v;
        Low[u] = Dfn[u] = ++Index;
        Stack[top++] = u;
        Instack[u] = true;
        for (int i = head[u]; i != -1; i = edge[i].next)
        {
            v = edge[i].to;
            if (!Dfn[v])
            {
                Tarjan(v);
                if (Low[u] > Low[v]) 
                    Low[u] = Low[v];
            }
            else if (Instack[v] && Low[u] > Dfn[v])
                Low[u] = Dfn[v];
        }
        if (Low[u] == Dfn[u])
        {
            scc++;
            do
            {
                v = Stack[--top];
                Instack[v] = false;
                Belong[v] = scc;
                num[scc]++;
            } while (v != u);
        }
    }
    
    int in[MAXN], out[MAXN];
    
    void solve(int N)
    {
        memset(Dfn,0,sizeof(Dfn));
        memset(Instack,false,sizeof(Instack));
        memset(num,0,sizeof(num));
        Index = scc = top = 0;
        for (int i = 1; i <= N; i++)
        {
            if (!Dfn[i])
                Tarjan(i);
        }
        if (scc == 1)
        {
            printf("1
    0
    ");
            return;
        }
        for (int i = 1; i <= scc; i++)
            in[i] = out[i] = 0;
        for (int u = 1; u <= N; u++)
        {
            for (int i = head[u]; i != -1; i = edge[i].next)
            {
                int v = edge[i].to;
                if (Belong[u] != Belong[v])
                {
                    in[Belong[v]]++;
                    out[Belong[u]]++;
                }
            }
        }
        int ans1 = 0, ans2 = 0;
        for (int i = 1; i <= scc; i++)
        {
            if (in[i] == 0) ans1++;
            if (out[i] == 0) ans2++;
        }
        //printf("%d
    ",scc);
        printf("%d
    %d
    ",ans1,max(ans1,ans2));
    }
    
    void init()
    {
        tot = 0;
        memset(head,-1,sizeof(head));
    }
    
    int main()
    {
        int n;
        int u, v;
        while (~scanf("%d", &n))
        {
            init();
            for (int i = 1; i <= n; i++)
            {
                while (~scanf("%d", &u) && u)
                {
                    addedge(i,u);
                }
            }
            solve(n);
        }
        return 0;
    }
  • 相关阅读:
    git clone 很慢提速方法
    在Windows上安装pytorch
    关于一些知名深度学习模型的转换
    【转】安装caffe2的参考
    Nasty Hacks
    寻梦
    Fibonacci Again
    统计元音
    首字母变大写
    查找最大元素
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7305063.html
Copyright © 2020-2023  润新知