POJ - 1236 Network of Schools
生活随笔
收集整理的這篇文章主要介紹了
POJ - 1236 Network of Schools
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a list of schools to which it distributes software (the “receiving schools”). Note that if B is in the distribution list of school A, then A does not necessarily appear in the list of school B
You are to write a program that computes the minimal number of schools that must receive a copy of the new software in order for the software to reach all schools in the network according to the agreement (Subtask A). As a further task, we want to ensure that by sending the copy of new software to an arbitrary school, this software will reach all schools in the network. To achieve this goal we may have to extend the lists of receivers by new members. Compute the minimal number of extensions that have to be made so that whatever school we send the new software to, it will reach all other schools (Subtask B). One extension means introducing one new member into the list of receivers of one school.
Input The first line contains an integer N: the number of schools in the network (2 <= N <= 100). The schools are identified by the first N positive integers. Each of the next N lines describes a list of receivers. The line i+1 contains the identifiers of the receivers of school i. Each list ends with a 0. An empty list contains a 0 alone in the line.
Output Your program should write two lines to the standard output. The first line should contain one positive integer: the solution of subtask A. The second line should contain the solution of subtask B.
Sample Input 5 2 4 3 0 4 5 0 0 0 1 0 Sample Output 1 2
You are to write a program that computes the minimal number of schools that must receive a copy of the new software in order for the software to reach all schools in the network according to the agreement (Subtask A). As a further task, we want to ensure that by sending the copy of new software to an arbitrary school, this software will reach all schools in the network. To achieve this goal we may have to extend the lists of receivers by new members. Compute the minimal number of extensions that have to be made so that whatever school we send the new software to, it will reach all other schools (Subtask B). One extension means introducing one new member into the list of receivers of one school.
Input The first line contains an integer N: the number of schools in the network (2 <= N <= 100). The schools are identified by the first N positive integers. Each of the next N lines describes a list of receivers. The line i+1 contains the identifiers of the receivers of school i. Each list ends with a 0. An empty list contains a 0 alone in the line.
Output Your program should write two lines to the standard output. The first line should contain one positive integer: the solution of subtask A. The second line should contain the solution of subtask B.
Sample Input 5 2 4 3 0 4 5 0 0 0 1 0 Sample Output 1 2
題意:
N個學校之間有單向的網絡,每個學校可以通過單向網絡向周邊的學校傳輸信息。
問題1:初始至少需要向多少個學校發放信息,使得網絡內所有的學校最終都能收到信息。
問題2:至少需要添加幾條邊,使得任意向一個學校發送信息后,經過若干次傳送,所有的學校都能收到信息。
題解:
分析題意發現其實就是問對于一個有向無環圖:
1.至少要選幾個點,才能從這些點出發到達所有點 。
2.至少加入幾條邊,就能從圖中任何一個點出發到達所有點。
當然圖不一定是無環圖,那么就用到了Tarjan算法來找到強連通分量,然后再縮點就變成了有向無環圖。
然后不難想出對于第一個問題答案就是有向無環圖中入度為0的點的個數。對于第二個問題仔細想一下就發現了如果要達到題意肯定每個點都有出有入,所以要消滅所有入度為零和出度為零的點,所以如果入度為0的個數是n,出度為0的個數是m,至少添加邊的條數就是max(n,m)。
代碼:
#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib>using namespace std;#define MAXN 205bool is_instack[MAXN];//記錄節點是否在棧中 int stack[MAXN],top; bool map[MAXN][MAXN];//存圖,這里用的矩陣僅供理解,具體做題自己調整。 int DFN[MAXN];//記錄節點第一次被訪問時的時間 int LOW[MAXN];//記錄節點與節點的子樹節點中最早的步數 int time; int Belong[MAXN];//記錄每個節點屬于的強連通分量編號 int N,cnt;//N是點數,cnt是強連通分量編號。void Tarjan(int x){DFN[x] = LOW[x] = ++time;is_instack[x] = true;stack[++top] = x;for(int i=1 ; i<=N ; ++i){if(map[x][i] == false)continue;if(!DFN[i]){Tarjan(i);if(LOW[i]<LOW[x]){LOW[x] = LOW[i];}}else if(is_instack[i] && DFN[i]<DFN[x]){ //這里注意不能直接else,因為DFN[i]!=0還有可能是橫叉邊。LOW[x] = min(LOW[x],DFN[i]);}}if(DFN[x] == LOW[x]){++cnt;int mid;do{mid = stack[top--];is_instack[mid] = false;Belong[mid] = cnt;}while(mid != x);} }int in[MAXN];//記錄縮點后點的入度 int out[MAXN];//記錄縮點后點的出度 void init(){memset(map,false,sizeof(map));memset(DFN,0,sizeof(DFN));memset(LOW,0,sizeof(LOW));memset(in,0,sizeof(in));memset(out,0,sizeof(out));memset(is_instack,false,sizeof(is_instack));time = 0;cnt = 0;top = 0; }int main(){while(scanf("%d",&N)!=EOF){init();for(int i=1 ; i<=N ; ++i){int t;while(scanf("%d",&t) && t)map[i][t] = true;}for(int i=1 ; i<=N ; ++i){if(!DFN[i])Tarjan(i);//有可能不是連通圖所以遍歷一遍。 }for(int i=1 ; i<=N ; ++i){for(int j=1 ; j<=N ; ++j){if(map[i][j] && Belong[i] != Belong[j]){++out[Belong[i]];++in[Belong[j]];}}}if(cnt==1){printf("1\n0\n");continue;}int inzero = 0,outzero = 0;for(int i=1 ; i<=cnt ; ++i){if(!in[i])++inzero;if(!out[i])++outzero;}printf("%d\n%d\n",inzero,max(inzero,outzero));}return 0; }轉載于:https://www.cnblogs.com/vocaloid01/p/9514080.html
總結
以上是生活随笔為你收集整理的POJ - 1236 Network of Schools的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 逆袭之旅DAY17.东软实训.Oracl
- 下一篇: TensorFlow 学习(3)——MN