7-9 红色警报
思路
这题的意思是,如果丢失一个城市会导致其他的城市分裂,就发出红色警报。
也就是说如果某块联通的城市,假设其中的某个节点A是中心节点,如果城市A失陷,那么其他城市将不再联通,这样输出红色警报。
每次都跑一遍并查集看看有几个不同的联通块,即使每个点都失陷,最大的复杂度也不超过2500000(2.5*10^6)。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=5005;
int from[maxn],to[maxn],vis[maxn],pre[maxn];
void init() {
for (int i=0;i<maxn;i++) {
pre[i]=i;
}
}
inline int find(int x) {
if (pre[x]==x) {
return x;
}
return pre[x]=find(pre[x]);
}
void unions(int x,int y) {
int fx=find(x);
int fy=find(y);
if (fx!=fy) {
pre[fx]=fy;
}
}
int getBlocks(int n) {
int res=0;
for (int i=0;i<n;i++) {
if (pre[i]==i) {
res++;
}
}
return res;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
init();
for (int i=0;i<m;i++) {
scanf("%d%d",&from[i],&to[i]);
unions(from[i],to[i]);
}
int total=getBlocks(n);
int k;
scanf("%d",&k);
int city;
int flag=n;
while (k--) {
init();
scanf("%d",&city);
vis[city]=1;
flag--;
for (int i=0;i<m;i++) {
int x=from[i];
int y=to[i];
if (vis[x]||vis[y]) {
continue;
}
unions(x,y);
}
int cur=getBlocks(n);
if (cur-total<=1) {
printf("City %d is lost.\n",city);
}
else {
printf("Red Alert: City %d is lost!\n",city);
}
total=cur;
}
if (!flag) {
printf("Game Over.\n");
}
return 0;
}