PAT甲級真題 1013 Battle Over Cities

一、題目
在這裏插入圖片描述
在這裏插入圖片描述
二、思路
題目給定一個無向圖及K個被佔領的點,要求出第k個點被佔領後,爲使圖連通所需增加的邊的數目。考察點:圖的構造及遍歷。
爲使圖連通所增加的最小數目的邊數,即,連通分量數-1。連通分量的數目可以通過遍歷求得。而去掉某個點,實際上可以通過把它看作一個獨立的連通分量,標記這個點已訪問過,這樣遍歷的時候就不會考慮它。
摘自柳神的分析:
在這裏插入圖片描述
三、代碼
這裏採用鄰接矩陣存儲圖、深度優先遍歷。

#include <stdio.h>

typedef struct {
	int vexs[1000];
	int arcs[1000][1000];
}graph;
graph g;//其實不需要vexs
int visited[1000] = { 0 }, n;//visited標記點的訪問情況,n爲頂點數目
//深度優先遍歷算法
void DFSA(int i) {
	int j;
	visited[i] = 1;
	for(j=0;j<n;j++)
		if((g.arcs[i][j]==1)&&(visited[j]==0))
			DFSA(j);
}

int main() {
	int m, c, i, j, k, p = 0,cnt;//m爲邊數,c爲要檢查的點數,i、j、k爲計數變量,cnt記錄連通分量數
	scanf("%d %d %d", &n, &m, &c);
	//初始化g
	for (i = 0; i < n; i++)
		g.vexs[i] = i + 1;
	for (k = 0; k < m; k++) {
		scanf("%d %d", &i, &j);
		g.arcs[i-1][j-1] = 1;
		g.arcs[j-1][i-1] = 1;//注意讀入的i、j和邊下標的區別
	}
	//讀入要檢查的點
	for (k = 0; k < c; k++) {
		cnt = 0;//每次讀入都要重新賦值cnt和visited
		for (i = 0; i < n; i++)
			visited[i] = 0;
		scanf("%d", &p);
		p = p - 1; 
		visited[p] = 1;//標記被去掉的點
		for (i = 0; i < n; i++) {
			if (visited[i] == 0) {
				DFSA(i);
				cnt++;
			}
		}
		printf("%d\n", cnt-1);//打印結果
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章