• POJ 1236 Network of Schools[连通分量]


    题目链接:http://poj.org/problem?id=1236
    题目大意:给出N台电脑,电脑间单向连通传送文件
    问题1.网络中最少放几个文件保证所有电脑都能接受到文件
    问题2.最少向网络中加几条线保证任意放1个文件所有电脑都能接受到
    解题思路:
    1.求出强连通分量
    2.缩点 ,进行重新构图
    3.如果入度为0,说明没有文件传输到该网络。解决问题1,统计入度为0的个数即可
    4.一个强连通图的入度和出度都不为0。入度为0相当于根root,出度为0相当于叶子leave.max(root, leave)即为答案。
    就是需要加的线数,保证整个网络强连通。
    若连通分量个数为0,那么答案为0

    代码如下:

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    using namespace std;
    #define N 105
    #define M 10005
    struct Edge
    {
        int v, next;
    }edge[M];
    
    int node[N], stack[N], instack[N], dfn[N], out[N], in[N];
    int low[N], belong[N], index, cnt_edge, n, m, cnt_tar, top;
    int ee[M][2];
    
    void add_Edge(int u, int v)
    {
        edge[cnt_edge].next=node[u];
        edge[cnt_edge].v=v;
        node[u]=cnt_edge++;
    }
    void tarjan(int u)
    {
        int i, j, v;
        dfn[u]=low[u]=++index;
        stack[++top]=u;
        instack[u]=1;
        for(i=node[u]; i!=-1; i=edge[i].next)
        {
            v=edge[i].v;
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u], low[v]);
            }
            else if(instack[v])
                low[u]=min(low[u], dfn[v]);
        }
        if(dfn[u]==low[u])
        {
            cnt_tar++;
            do
            {
                j=stack[top--];
                instack[j]=0;
                belong[j]=cnt_tar;
            }while(j!=u);
        }
    
    }
    void solve()
    {
        int i;
        top=0, index=0, cnt_tar=0;
        memset(dfn, 0, sizeof(dfn));
        memset(low, 0, sizeof(low));
        for(i=1; i<=n; i++)
            if(!dfn[i])
                tarjan(i);
    }
    int main()
    {
        int i, u, v;
        while(scanf("%d", &n)!=EOF)
        {
            cnt_edge=0, m=1;
            memset(node, -1, sizeof(node));
            memset(in, 0, sizeof(in));
            memset(out, 0, sizeof(out));
            for(i=1; i<=n; i++)
            {
                while(scanf("%d", &v))
                {
                    if(v==0) break;
                    ee[m][0]=i, ee[m++][1]=v;
                    add_Edge(i, v);
                }
            }
            solve();
            for(i=1; i<=m; i++)
            {
                int xx=belong[ee[i][0]], yy=belong[ee[i][1]];
                if(xx!=yy)
                {
                    in[yy]++;
                    out[xx]++;
                }
            }
            int innum=0, outnum=0;
            for(i=1; i<=cnt_tar; i++)
            {
                if(in[i]==0)
                    innum++;
                if(out[i]==0)
                    outnum++;
            }
            if(cnt_tar==1)
                printf("1
    0
    ");
            else
                printf("%d
    %d
    ", innum, max(innum, outnum));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    iframe
    # ? & 号在url中的的作用
    面向对象和面向过程
    dom
    DOM对象与jquery对象有什么不同
    绑定js
    leetcode — search-for-a-range
    leetcode — search-for-a-range
    leetcode — search-in-rotated-sorted-array
    leetcode — longest-valid-parentheses
  • 原文地址:https://www.cnblogs.com/Hilda/p/3226718.html
Copyright © 2020-2023  润新知