题目描述
Sample Input
3 2 3
1 2
1 3
1 2 3
Sample Output
1
0
0
思路
主要用并查集的思路。
相互连通的城市群构成一个集合,它们有相同的代表元(father)。
求出炸毁一个城市后,其他城市构成的并查集的个数n。如果想要这些城市群互相连通,只要再建造(n-1)条路即可。
AC代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<pair<int,int> > roads;
int father[1001];
/*
* find the father of vertex v
*/
int findFather(int v){
return father[v]==v?v:findFather(father[v]);
}
int main(){
int N,M,K;
cin>>N>>M>>K;
//Input roads
for(int i = 0;i<M;++i){
int vA,vB;
cin>>vA>>vB;
roads.push_back(pair<int,int>(vA,vB));
}
//Check
for(int i = 1;i<=K;++i){
//input the vertex to be deleted
int delV;
cin>>delV;
//initialization
for(int i = 1;i<=N;++i)
father[i] = i;
//create union-find sets
for(vector<pair<int,int> >::iterator it = roads.begin();it!= roads.end();++it){
if((*it).first != delV && (*it).second != delV){
int fatherA = findFather((*it).first),
fatherB = findFather((*it).second);
if(fatherA != fatherB){
father[fatherB] = fatherA;
}
}
}
//find the number of distinct sets
vector<int> fathers;
for(int j = 1;j<=N;++j){
if(j!=delV){
int f = findFather(j);
if(find(fathers.begin(),fathers.end(),f)== fathers.end())
fathers.push_back(f);
}
}
//Output
if(!fathers.empty())
cout<<fathers.size()-1<<endl;
}
//if special cases
if(K == 0 || N == 0)
cout<<0<<endl;
return 0;
}