第三部分 數據結構 -- 第四章 圖論算法-1383:刻錄光盤(cdrom)

1383:刻錄光盤(cdrom)

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 2798 通過數: 1121
【題目描述】
在FJOI2010夏令營快要結束的時候,很多營員提出來要把整個夏令營期間的資料刻錄成一張光盤給大家,以便大家回去後繼續學習。組委會覺得這個主意不錯!可是組委會一時沒有足夠的空光盤,沒法保證每個人都能拿到刻錄上資料的光盤,怎麼辦呢?!

DYJ分析了一下所有營員的地域關係,發現有些營員是一個城市的,其實他們只需要一張就可以了,因爲一個人拿到光盤後,其他人可以帶着U盤之類的東西去拷貝啊!

他們願意某一些人到他那兒拷貝資料,當然也可能不願意讓另外一些人到他那兒拷貝資料,這與我們FJOI宣揚的團隊合作精神格格不入!!!

現在假設總共有N個營員(2≤N≤200),每個營員的編號爲1~N。DYJ給每個人發了一張調查表,讓每個營員填上自己願意讓哪些人到他那兒拷貝資料。當然,如果A願意把資料拷貝給B,而B又願意把資料拷貝給C,則一旦A獲得了資料,則B,C都會獲得資料。

現在,請你編寫一個程序,根據回收上來的調查表,幫助DYJ計算出組委會至少要刻錄多少張光盤,才能保證所有營員回去後都能得到夏令營資料?

【輸入】
先是一個數N,接下來的N行,分別表示各個營員願意把自己獲得的資料拷貝給其他哪些營員。即輸入數據的第i+1行表示第i個營員願意把資料拷貝給那些營員的編號,以一個0結束。如果一個營員不願意拷貝資料給任何人,則相應的行只有1個0,一行中的若干數之間用一個空格隔開。

【輸出】
一個正整數,表示最少要刻錄的光盤數。

【輸入樣例】
5
2 4 3 0
4 5 0
0
0
1 0
【輸出樣例】
1


思路:檢查圖的連通性,判斷有多少環, 初始map數組表示 第i個營員的父親是自身,然後如果第i個人和第j個人相連,就把第j個人的父親更新爲與第i個人父親一樣,最後統計有多少個人的父親是自身。

#include<cstdio>
#include<iostream>
#include<cstring>
#define N 1000
using namespace std;
int n;
int map[N][N];
int p[N];
int main(){
	memset(map,0,sizeof(map));
	scanf("%d",&n);
	for(int i = 0 ; i <= n; i++)
	p[i] = i;
	for(int i = 1; i <= n; i++)
	{
		int x;
		while(scanf("%d",&x) && x != 0){
			map[i][x] = 1;
		}
	}
	for(int k = 1; k <=n; k++){
	
	  for(int i = 1; i<= n; i++){
	  
	   for(int j = 1; j <= n; j++)
	    {
	    	map[i][j] = map[i][j] || (map[i][k] && map[k][j]);
		}
	}
}
for(int i = 1; i <= n; i++){

  for(int j = 1; j <= n; j++)
  {
  	if(map[i][j]){
  		p[j] = p[i];//p[i]是p[j]的父節點
	  }
  }
}
int cnt = 0;
for(int i = 1; i <= n; i++){
	if(p[i] == i){
		cnt++;
	}
}
printf("%d\n",cnt);
	return 0;
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章