原题干:
It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any other highways to keep the rest of the cities connected. Given the map of cities which have all the remaining highways marked, you are supposed to tell the number of highways need to be repaired, quickly.
For example, if we have 3 cities and 2 highways connecting city1-city2 and city1-city3. Then if city1 is occupied by the enemy, we must have 1 highway repaired, that is the highway city2-city3.
Input
Each input file contains one test case. Each case starts with a line containing 3 numbers N (<1000), M and K, which are the total number of cities, the number of remaining highways, and the number of cities to be checked, respectively. Then M lines follow, each describes a highway by 2 integers, which are the numbers of the cities the highway connects. The cities are numbered from 1 to N. Finally there is a line containing K numbers, which represent the cities we concern.
Output
For each of the K cities, output in a line the number of highways need to be repaired if that city is lost.
Sample Input
3 2 3 1 2 1 3 1 2 3
Sample Output
1 0 0
题目大意:
有N个城市,这些城市之间有M条铁路相连。假设如果某个城市被别人侵占,则这个城市与它直接相连的所有铁路将不复存在。求问需要增加几条铁路线能重新把所有城市连接起来。
第一行输入N M K
接着给出M行数据,每行两个数字代表这两个城市间有铁路相连。
最后一行给出K个数据,分别假设这k的城市被侵占,依次输出需要增加多少铁路线。
其实这道题就是一个很简单的图的遍历问题。城市为顶点,铁路为边。相连的城市一定处于同一个连通块内,不处于同一个连通块内的城市一定不相连,这就需要修一条铁路。
这个问题就转化为了求有多少块连通块的问题。
我们知道,每次遍历顶点的时候只能遍历同一个连通块,所以我们就计算一下能遍历多少次顶点就好了。
这里需要注意:
-
城市被侵占,顶点被删除,其实不用真正的删除顶点,只需要把要删除的顶点标记为"访问过",遍历的时候就不会去访问顶点,也不会走那条边了
-
对于每一个查询,在查询前要使用memset或者遍历的方式,将标记数组全部归False
-
输出的数据为连通块-1。比如图有三个连通块,则只需要建2条路即可把他们全部连接。
下面是代码:
#include <iostream>
using namespace std;
#define MAXN 1010
int G[MAXN][MAXN] = {0};
bool visited[MAXN] = {false};
int n, m, k;
void DFS(int v){
visited[v] = true;
for(int i = 1; i <= n; i++)
if(!visited[i] && G[v][i])
DFS(i);
}
int DFSG(){
int cnt = -1;
for(int i = 1; i <= n; i++){
if(!visited[i]){
DFS(i);
cnt++;
}
}
return cnt;
}
void init(){ //初始化。可以使用memset代替
for(int i = 1; i <= n; i++)
visited[i] = false;
}
int main(){
cin >> n >> m >> k;
for(int i = 0; i < m; i++){
int tmp1, tmp2;
cin >> tmp1 >> tmp2;
G[tmp1][tmp2] = G[tmp2][tmp1] = 1;
}
while(k--){
int tmp;
cin >> tmp;
init();
visited[tmp] = true;
cout << DFSG() << endl;
}
return 0;
}