【解题思路】
每一次都要重新判断一下需要连接的道路变化有无影响
有影响的情况比较难找,那就直接先判断没有影响的情况
就是等于前集合数目等于现集合数目或原集合数目+1等于现集合数目(因为题意,若该国本来就不完全连通,是分裂的k个区域,而失去一个城市并不改变其他城市之间的连通性,则不要发出警报)
这样即使去掉当前结点也无碍
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn 5020
int father[maxn];
int vis[maxn];
struct node {
int x,y;
}Node[maxn];
void init()
{
for(int i=0;i<maxn;i++)
{
father[i]=i;
}
}
/*int findFather(int x)
{
while (x!=father[x])
{
x=father[x];
}
return x;
}*/
int findFather(int x)
{
return x==father[x]?father[x]:findFather(father[x]);
}
void Union(int a,int b)
{
int faA=findFather(a);
int faB=findFather(b);
if(faA!=faB)
father[faA]=faB;
}
int main()
{
int n,m;
while (~scanf("%d%d",&n,&m))
{
init();
memset(vis, 0, sizeof(vis));
for(int i=0;i<m;i++)
{
scanf("%d%d",&Node[i].x,&Node[i].y);
Union(Node[i].x, Node[i].y);
}
int num=0;
for(int i=0;i<n;i++)
{
if(father[i]==i)
num++;
}
int k;
scanf("%d",&k);
int num1=0;
while (k--)
{
for(int i=0;i<n;i++)
{
father[i]=i;//之前攻占之后的连通情况发生改变,要进行初始化
}
num1=0;
int h;
scanf("%d",&h);
vis[h]=1;
for(int i=0;i<m;i++)
{
if(vis[Node[i].x]==0&&vis[Node[i].y]==0)
Union(Node[i].x, Node[i].y);
}
for(int i=0;i<n;i++)
{
if(father[i]==i)
num1++;
}
if(num1==num||(num+1==num1))//不改变其他城市的连通性
printf("City %d is lost.\n",h);
else
printf("Red Alert: City %d is lost!\n",h);
num=num1;
}
num=0;
for(int i=0;i<n;i++)
{
if(vis[i]==1)
num++;
}
if(num==n)
printf("Game Over.\n");
}
return 0;
}