PTA 一 紅色警報

戰爭中保持各個城市間的連通性非常重要。本題要求你編寫一個報警程序,當失去一個城市導致國家被分裂爲多個無法連通的區域時,就發出紅色警報。注意:若該國本來就不完全連通,是分裂的k個區域,而失去一個城市並不改變其他城市之間的連通性,則不要發出警報。

輸入格式:

輸入在第一行給出兩個整數N(0 << N \le 500)和M\le 5000),分別爲城市個數(於是默認城市從0到N-1編號)和連接兩城市的通路條數。隨後M行,每行給出一條通路所連接的兩個城市的編號,其間以1個空格分隔。在城市信息之後給出被攻佔的信息,即一個正整數K和隨後的K個被攻佔的城市的編號。

注意:輸入保證給出的被攻佔的城市編號都是合法的且無重複,但並不保證給出的通路沒有重複。

輸出格式:

對每個被攻佔的城市,如果它會改變整個國家的連通性,則輸出Red Alert: City k is lost!,其中k是該城市的編號;否則只輸出City k is lost.即可。如果該國失去了最後一個城市,則增加一行輸出Game Over.

輸入樣例:

5 4
0 1
1 3
3 0
0 4
5
1 2 0 4 3

輸出樣例:

City 1 is lost.
City 2 is lost.
Red Alert: City 0 is lost!
City 4 is lost.
City 3 is lost.
Game Over.

算法思路:利用深度優先遍歷計算圖的連通分量數。

每丟失一個城池更新一次連通分量數,並與原來的連通分量數進行比較。連通分量數增加則是紅色警報

易錯點:如果一個節點本來就是單獨的一個連通分支,丟失這個節點之後連通分量數減少1。


#include<stdio.h>
#include<vector>
using namespace std;

vector<int> citys;
int map[500][500];
bool vis[500];
int componentSize;
int n;

int getFirstNeib(int v){
	for(int i=0;i<citys.size();i++){
		if(map[v][citys[i]]!=0)
			return i;
	}
	return -1;
}

int getNextNeib(int v,int w){
	for(int i=w+1;i<citys.size();i++){
		if(map[v][citys[i]]!=0)
			return i;
	}
	return -1;
}

void DFS(int v){
	int i;
	vis[v]=true;
	int w=getFirstNeib(v);
	while(w!=-1){
		if(vis[citys[w]]==false) DFS(citys[w]);
		w=getNextNeib(v,w);
	}
}

void flushComponentCounts(){
	componentSize=0;
	int i;
	for(i=0;i<citys.size();i++) vis[citys[i]]=false;
	for(i=0;i<citys.size();i++){
		if(!vis[citys[i]]){
			DFS(citys[i]);
			componentSize++;
		}
	}
}

void move(int x){
	for(vector<int>::iterator it=citys.begin();it!=citys.end();it++)
		if(*it==x) {citys.erase(it);return;}
}

void init(){
	int i,j;
	for(i=0;i<n;i++){
		citys.push_back(i);
		vis[i]=false;
		for(j=0;j<n;j++)
			map[i][j]=0;
	}
}

int main(){
	int m;
	scanf("%d%d",&n,&m);
	init();
	int i;
	for(i=0;i<m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		map[x][y]=map[y][x]=1;
	}
	flushComponentCounts();
	int k;
	scanf("%d",&k);
	for(i=1;i<=k;i++) {
		int x;
		scanf("%d",&x);
		move(x);
		int comptemp=componentSize;
		flushComponentCounts();
		if(comptemp>=componentSize) printf("City %d is lost.\n",x);
		else printf("Red Alert: City %d is lost!\n",x);
	}
	if(k==n) printf("Game Over.\n");
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章