1013 Battle Over Cities (25分)
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 Specification:
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 Specification:
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:城市总数目 [1,1000)
- M:道路总数目(并输入连接的两个城市的编号)
- K:可能被敌军占领的城市数目(并输入可能被占领的城市编号)
要求求出:当敌军占领某个城市后,该城市以及与该城市连通的道路被销毁,求还需要增加多少条道路使剩下的城市连通?
二、解题思路:
单独的n个城市连通最少需要n-1条道路即可;若n个城市之间已有连通,求出当前的连通量cnt,则还需cnt-1条道路。
本题实际问题即为:图的存储、连通量的求解——图的遍历(DFS/BFS)
- 如何存储城市及其之间的道路呢?
- 对图的存储有:链表、二维矩阵(个人比较习惯使用二维矩阵)
- 如何求得剩余城市的连通量呢?
- 首先找出剩余有哪些城市:开一个visited监视哨数组作为标记
- 连通量的求解:图的遍历
- 使用深度优先搜索DFS:每当深度搜索到尽头,连通数量+1
- 搜索的过程:
(2.1)要求得剩余城市的连通数量:将销毁点置为已访问状态,起始搜索点从未访问点开始;
(2.2)深度搜索的条件:相连通、未访问状态
- 注意事项:
- 由于有多个可能销毁城市:每一次的连通量求解都要首先置监视哨数组为未访问状态
- 最后提交会有一个测试点超时:c++中的cin、cout(先把要输出的东西存入缓冲区,再输出,导致效率降低),所以使用c语言中的printf、scanf不会超时。
#include <iostream>
#include <cstring>
using namespace std;
int visited[1001]={0};
int city[1001][1001]={9999}; //道路全部初始化为不可达
int n; //城市数[1,999]
void dfs(int node){
visited[node]=1;
for(int i=1;i<=n;i++){
if(visited[i]==0&&city[node][i]==1){ //未访问过且与node节点相连接
dfs(i);
}
}
}
int main()
{
int m; //道路数
int k; //战乱城市数
scanf("%d%d%d",&n,&m,&k);
int x,y;
int cnt[k+1]={0};
int z;
for(int i=1;i<=m;i++){ //m条道路置为1
scanf("%d%d",&x,&y);
city[x][y]=city[y][x]=1;
}
//所需道路数=剩余连通分量-1
for(int i=1;i<=k;i++){
scanf("%d",&z);
memset(visited,0,sizeof(visited)); //将所有城市访问状态置为未访问状态
visited[z]=1; //必须放在初始化visited数组后面
for(int j=1;j<=n;j++){
if(visited[j]==0){ //遍历每个点求城市被占领后的连通分量
dfs(j);
cnt[i]++;
}
}
printf("%d\n",cnt[i]-1);
}
return 0;
}
探讨在战争中城市间高速公路受损时,快速计算修复剩余城市连通性所需新增道路数量的方法。通过图的存储与遍历算法,如DFS,解决连通量求解问题。
&spm=1001.2101.3001.5002&articleId=104068973&d=1&t=3&u=386e1e2ec95c420c91a1eecc743e98f0)
446

被折叠的 条评论
为什么被折叠?



