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,那麼答案爲0node

代碼以下:ios

#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\n0\n");
        else
            printf("%d\n%d\n", innum, max(innum, outnum));
    }
    return 0;
}
View Code
相關文章
相關標籤/搜索