将题目翻译过来就是求去掉某一顶点后的连通分支数-1,因为要保持剩余的城市彼此之间是connected的,只需要在连通分支间添加一条公路即可。
可以用dfs求图的连通分支数,占领一座城市需要将该城市关联的边都要去掉,对dfs的影响其实就是无法访问该顶点关联的边,在dfs之前提前vis[该顶点]=true,这样深度优先搜索的时候遇到该顶点就不会搜他的邻接点,也就相当于去掉了该城市所有关联边的效果。
还有注意一些极端样例比如1 0 1 1,即只有一个城市,且它被侵占,结果应为0,但是按照正常的算法没有顶点访问到res会不变即为初值0,在res-1就会得到-1,因此输出时需要特判一下即可。
比较弱智的是一开始手误将
G[v].push_back(w);
G[w].push_back(v);
写成了
G[v].push_back(w);
G[w].push_back(w);
离谱的是还得了17分,呜呜写代码一定要仔细小心啊
完整代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
vector<int> G[1005];
bool vis[1005]={false};
void dfs(int v){
vis[v]=true;
for(auto w:G[v]){
if(!vis[w]){
dfs(w);
}
}
}
int main() {
#ifdef ONLINE_JUDGE
#else
freopen("1.txt","r",stdin);
#endif
int N,M,K;
cin >> N >> M >> K;
for(int i=0;i<M;i++){
int v,w;
cin >> v >> w;
G[v].push_back(w);
G[w].push_back(v);
}
//采用dfs来求连通分支数
while(K--){
int del;
cin >> del;
for(int i=1;i<=N;i++)
vis[i]=false;
vis[del]=true;//删除这个城市相当于提前访问过了
int res=0;//统计连通分支数
for(int i=1;i<=N;i++){
if(!vis[i]){
res++;
dfs(i);
}
}
cout << max(0,res-1) << endl;
}
return 0;
}