PAT.1013 Battle Over Cities - 并查集
题目链接
一开始的想法是判定所有节点是否在环上,如果查询节点不在环上答案就是相连路径数-1,如果在环上就是0,对应就用删除叶子节点的算法来标记。
然后发现这样写比较麻烦,于是干脆对每次查询都用一次并查集来判断剩余连通分量的个数,答案就是删去目标节点后连通分量个数-1。
题解
把路径压缩放在getAnc函数里,同时将每个节点的初始最大祖先设为自己而非0,避免了以前用大量if的写法。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<pair<int,int>> roads;
int anc[1005];
int cityCnt,roadCnt,queryCnt,city,city1,city2,comps,anc1,anc2;
int getAnc(int a){
if(anc[a] != a) anc[a] = getAnc(anc[a]);
return anc[a];
}
int main(){
cin>>cityCnt>>roadCnt>>queryCnt;
for(int i = 0 ; i < roadCnt ; ++i){
cin>>city1>>city2;
roads.push_back({city1,city2});
}
for(int i = 0 ; i < queryCnt ; ++i){
cin>>city;
comps = cityCnt - 1;
for(int j = 1 ; j <= cityCnt ; ++j) anc[j] = j;
for(int j = 0 ; j < roadCnt ; ++j){
city1 = roads[j].first;
city2 = roads[j].second;
if(city1 == city || city2 == city) continue;
if(getAnc(city1) != getAnc(city2)){
anc[getAnc(city2)] = getAnc(city1);
comps--;
}
}
cout<<comps-1<<endl;
}
}