题目内容:
题目意思说给N个城市,M条城市与城市之间相连的边,K个每次要去除的城市,输出去除第k个城市后需要几条边才能使其余的城市连接在一块。
解题思路:
使用并查集,将给出的M条边去除含有删除城市的边使用并查集相连,统计分为了几个集合,最后集合数-1就是答案,集合数-1是因为n个点相连仅需要n-1条线,最后使用并查集要用压缩路径,否则最后一个测试点会超时。
代码:
#include <bits/stdc++.h>
#include <cstdio>
using namespace std;
int f[1005];
vector <int>u1,v1;
int find(int a)
{
int b=a; //把初始值赋给b
while(a!=f[a]){
a=f[a]; //找到a的祖先节点
}
while(b!=a){ //直到b==a为止
int temp=f[b]; //设一个中间变量为b的父亲节点
f[b]=a; //直接让b的父亲节点为a的祖先节点
b=temp; //b等于b的父亲节点
}
return a;
}
void Union(int x,int y)
{
int fx,fy;
fx=find(x);
fy=find(y);
if(fx!=fy)
f[fx]=fy;
}
void init()
{
for(int i=1;i<=1000;i++)
f[i]=i;
}
int main()
{
int n,m,k,u,v,t;
scanf("%d %d %d",&n,&m,&k);
for(int i=1;i<=m;i++)
{
scanf("%d %d",&u,&v);
u1.push_back(u);
v1.push_back(v);
}
for(int i=1;i<=k;i++)
{
init();
cin>>t;
for(int j=0;j<m;j++)//连接除了要删除节点以外城市的边
{
if(u1[j]==t||v1[j]==t)
continue;
else
Union(u1[j],v1[j]);
}
int sum=0;
for(int j=1;j<=n;j++)//统计有几个集合
{
if(f[j]==j&&j!=t)
sum++;
}
printf("%d\n",sum-1);
}
}