一、題目
二、思路
題目給定一個無向圖及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;
}