PTA——1013 Battle Over Cities 並查集/連通集/pair
阿新 • • 發佈:2021-02-14
題目描述
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;
}