题目:1013. Battle Over Cities (25)
思路:1. 利用并查集,剔除掉选中城市的道路,构建无向联通图。通过代表元的个数来计算需要搭建的道路数。
2.利用深度优先搜索。
代码:并查集
#include<iostream>
#include<vector>
using namespace std;
struct road
{
int x,y;
};
//初始化根节点
void init(int *c,int n)
{
int i;
for(i=1;i<=n;++i)
c[i]=i;
}
//查找根节点
int findroot(int *c,int j)
{
if(c[j]==j)
return j;
else
{
int t=findroot(c,c[j]);
c[j]=t;
return t;
//return findroot(c,c[j]);
//仅用上面这一条,会出现同一个连接图,根节点不一样的情况
}
}
//构建连通图
void makeset(int *c,int k,vector<road> r)
{
int i,a,b;
for(i=0;i<r.size();++i)
{
if(r[i].x!=k && r[i].y!=k)//避免选中城市加入连通图
{
a=findroot(c,r[i].x);
b=findroot(c,r[i].y);
if(a!=b)
c[a]=b; //根节点改变
}
}
}
int main()
{
//输入
int N,M,K;
cin>>N>>M>>K;
int i,n1,n2,n;
vector<road> R(M);
//输入城市联通信息,并加以排序
//避免出现由于先出现编号大的城市导致根节点不一致的情况。
for(i=0;i<M;++i)
{
cin>>n1>>n2;
R[i].x=n1;
R[i].y=n2;
}
vector<int> q(K);
for(i=0;i<K;++i)
cin>>q[i];
//查找
int j,k,num;
int city[1000];
for(i=0;i<K;++i)
{
init(city,N); //初始化节点
makeset(city,q[i],R);
num=0;
for(j=1;j<=N;++j)
{
if(city[j]==j)
num++;
}
cout<<num-2<<endl; //-2,一是减去被选中的城市,而是num个独立城市之间需要num-1条道路
}
system("pause");
return 0;
}