GPLT L2-013. 红色警报 判连通度

题目链接在此

本来只是一个直接求连通度的问题,但是题说:"注意:若该国本来就不完全连通,是分裂的k个区域,而失去一个城市并不改变其他城市之间的连通性,则不要发出警报。 "意思即去除“悬挂点”或者“孤立点”不要发出警报。

这个地方怎么绕..方法是删掉边之后不要去除该城市,一样把被攻占的点放在连通度里考虑,这样做能够忽略这两种特别的点带来的影响.

在上面这个处理方法前提下,若删除后,把一个连通块分成2部分,实际上这个块的连通度由1变成了3。打个比方,A--B--C,删除B(仅仅断两条边),又保留B,连通度为3了。若只是变成了2,说明切出来了一个孤立点,实际连通度不变.比如(A)----(B),切去(A),相当于断一条边,连通度由1变成2。综上所述,若去掉点后连通度和去掉之前的连通度相差>=2,则需要警报,否则不需要。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

#define mst(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<(b);++i)
const int inf = 0x3f3f3f3f, maxN = 505;
int N, M;
int G[maxN][maxN], vis[maxN];

void dfs(int s) {
    vis[s] = 1;
    rep(i, 0, N)
        if (G[s][i] && !vis[i])
            dfs(i);
}
int city() {
    int cnt = 0;
    mst(vis, 0);
    rep(i, 0, N) {
        if (!vis[i]) {
            ++cnt;
            dfs(i);
        }
    }
    return cnt;
}

int main() {
    // freopen("data.in", "r", stdin);
    scanf("%d %d", &N, &M);
    int a, b;
    mst(G, 0);
    rep(i, 0, M) {
        scanf("%d %d", &a, &b);
        G[a][b] = G[b][a] = 1;
    }
    int T, lo, before, after;
    before = city();

    scanf("%d", &T);
    rep(i, 0, T) {
        scanf("%d", &lo);
        rep(j, 0, N)
            G[j][lo] = G[lo][j] = 0;
        after = city();
        if (after > before + 1)
            printf("Red Alert: City %d is lost!\n", lo);
        else
            printf("City %d is lost.\n", lo);
        before = after;

        if (i == N - 1) {
            printf("Game Over.");
        }
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。