• POJ 1236 Network of Schools


    题目大意:

    给定一个有向图,求:
    1) 至少要选几个顶点,才能做到从这些顶点出
       发,可以到达全部顶点
    2) 至少要加多少条边,才能使得从任何一个顶
     点出发,都能到达全部顶点
       顶点数<= 100

    有用的定理:

    有向无环图中所有入度不为0的点,。一定可以由某个入度为0的点出发可达由于无环,所以从任何入度不为0的点往回走必然终止于一个入度为0的点

    解题思路:

    1. 求出所有强连通分量

    2. 每个强连通分量缩成一点,则形成一个有向无环图DAG。

    3. DAG上面有多少个入度为0的顶点,问题1的答案就是多少

    在DAG上要加几条边,才能使得DAG变成强连通的,问题2的答案就是多少

     加边的方法:要为每个入度为0的点添加入边,为每个出度为0的点添加出边假定有 n 个入度为0的点,m个出度为0的点,max(m,n)就是第二个问题的解(证明难,略)

     但是比较好想, 我要让那些入度为0,和 出度为 0,的点变为不为 0,这样我们可以形成完全联通,我们一个入度为 0 的连接一个出度为 0 的,可以消失两对,剩下的,我们每个

    再随便加一条边就可以了。

    当我们求出强联通分量之后就可以,然后重新构图, 最后得出结果, 有一个答案要特殊判断一下, 因为只有一个强联通分量的时候是不需要多加边,因此要特殊判断一下。

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <cmath>
    #include <stack>
    #include <cstring>
    usingnamespace std;
    #define INF 0xfffffff
    #define maxn 105
    #define min(a,b) (a<b?a:b)
    bool InStack[maxn];
    int low[maxn], dfn[maxn], Stack[maxn], top, time, cnt;
    int maps[maxn][maxn];
    int belong[maxn];
    int n;
    vector<int> G[maxn];
    
    void Init()
    {
        memset(low, 0, sizeof(low));
        memset(dfn, 0, sizeof(dfn));
        memset(InStack, false, sizeof(InStack));
        memset(maps, 0, sizeof(maps));
        cnt = time = top = 0;
    
        for(int i=0; i<=n; i++)
            G[i].clear();
    }
    
    void Tarjan(int u)
    {
        low[u] = dfn[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];
                belong[v] = cnt;
                InStack[v] = false;
            }while(u != v);
            cnt ++;
        }
    }
    
    void solve()
    {
        int InDegree[maxn] = {0};
        int OutDegree[maxn] = {0};
        int In = 0, Out = 0;
    
        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];
                maps[belong[i] ][belong[v] ] = 1;
            }
        }
    
        for(int i=0; i<cnt; i++)
        {
            for(int j=0; j<cnt; j++)
            {
                if( i == j)
                    continue;
    
                if(maps[i][j])
                {
                    InDegree[j] ++;
                    OutDegree[i] ++;
                }
            }
        }
    
        for(int i=0; i<cnt; i++)
        {
            if(InDegree[i] == 0)
                In ++;
            if(OutDegree[i] == 0)
                Out ++;
        }
    
        printf("%d
    ", In);
    
        if(cnt == 1)
            printf("0
    ");
        else
            printf("%d
    ", max(In, Out));
    }
    
    
    int main()
    {
        while(scanf("%d", &n) != EOF)
        {
            Init();
            for(int i=1; i<=n; i++)
            {
                int a;
                while(scanf("%d",&a), a)
                    G[i].push_back(a);
            }
    
            solve();
        }
        return0;
    }

     

  • 相关阅读:
    使用react+html2canvas+jspdf实现生成pdf文件
    命名函数表达式
    java-信息安全(二十)国密算法 SM1,SM2,SM3,SM4
    003-docker-单宿主机下的网络模式
    【性能扫盲】性能测试面试题
    LoadRunner函数
    爬取干货集中营的美女图片
    ELK 性能优化实践 ---总结篇
    ELK 性能优化实践
    告警图片-搞笑的
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4718700.html
Copyright © 2020-2023  润新知