1. 程式人生 > >洛谷P2746 [USACO5.3]校園網Network of Schools

洛谷P2746 [USACO5.3]校園網Network of Schools

rdquo 接下來 from cow tarjan work 所有 其余 需要

P2746 [USACO5.3]校園網Network of Schools

題目描述

一些學校連入一個電腦網絡。那些學校已訂立了協議:每個學校都會給其它的一些學校分發軟件(稱作“接受學校”)。註意即使 B 在 A 學校的分發列表中, A 也不一定在 B 學校的列表中。

你要寫一個程序計算,根據協議,為了讓網絡中所有的學校都用上新軟件,必須接受新軟件副本的最少學校數目(子任務 A)。更進一步,我們想要確定通過給任意一個學校發送新軟件,這個軟件就會分發到網絡中的所有學校。為了完成這個任務,我們可能必須擴展接收學校列表,使其加入新成員。計算最少需要增加幾個擴展,使得不論我們給哪個學校發送新軟件,它都會到達其余所有的學校(子任務 B)。一個擴展就是在一個學校的接收學校列表中引入一個新成員。

輸入輸出格式

輸入格式:

輸入文件的第一行包括一個整數 N:網絡中的學校數目(2 <= N <= 100)。學校用前 N 個正整數標識。

接下來 N 行中每行都表示一個接收學校列表(分發列表)。第 i+1 行包括學校 i 的接收學校的標識符。每個列表用 0 結束。空列表只用一個 0 表示。

輸出格式:

你的程序應該在輸出文件中輸出兩行。

第一行應該包括一個正整數:子任務 A 的解。

第二行應該包括子任務 B 的解。

輸入輸出樣例

輸入樣例#1: 復制
5
2 4 3 0
4 5 0
0
0
1 0
輸出樣例#1: 復制
1
2

說明

題目翻譯來自NOCOW。

USACO Training Section 5.3

/*
    根據題意這是一個連通圖,所以不用建雙向邊bfs找聯通塊
    兩問簡單的來說就是:
    A.求縮點後入度為零的點的個數
    B.求縮點後max{入度為零的點的個數,出度為零的點的個數} 
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define maxn 101
using
namespace std; int n,num,head[maxn],num2,head2[maxn]; int dfn[maxn],low[maxn],g_num,cnt,st[maxn],top,belong[maxn]; int ru[maxn],chu[maxn]; bool vis[maxn],con[maxn][maxn]; struct node{ int from,to,pre; }e[maxn*maxn]; void Insert(int from,int to){ e[++num].to=to; e[num].from=from; e[num].pre=head[from]; head[from]=num; } void Tarjan(int u){ cnt++;dfn[u]=low[u]=cnt;st[++top]=u;vis[u]=1; for(int i=head[u];i;i=e[i].pre){ int v=e[i].to; if(!dfn[v]){ Tarjan(v); low[u]=min(low[u],low[v]); } else { if(vis[v])low[u]=min(low[u],dfn[v]); } } if(dfn[u]==low[u]){ g_num++; while(st[top]!=u){ int x=st[top];top--; vis[x]=0; belong[x]=g_num; } int x=st[top];top--; vis[x]=0; belong[x]=g_num; } } int main(){ scanf("%d",&n); int x; for(int i=1;i<=n;i++) while(1){ scanf("%d",&x); if(x==0)break; Insert(i,x); } for(int i=1;i<=n;i++) if(!dfn[i])Tarjan(i); for(int i=1;i<=num;i++){ if(belong[e[i].from]!=belong[e[i].to]){ ru[belong[e[i].to]]++; chu[belong[e[i].from]]++; } } int cnt1=0,cnt2=0; for(int i=1;i<=g_num;i++){ if(ru[i]==0)cnt1++; if(chu[i]==0)cnt2++; } if(g_num==1)printf("1\n0"); else printf("%d\n%d",cnt1,max(cnt1,cnt2)); }

洛谷P2746 [USACO5.3]校園網Network of Schools