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;
}

posted @ 2020-02-18 22:05  xyee  阅读(293)  评论(0编辑  收藏  举报