L2-013 红色警报 (25 分)(并查集)

简介: L2-013 红色警报 (25 分)(并查集)

战争中保持各个城市间的连通性非常重要。本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报。注意:若该国本来就不完全连通,是分裂的k个区域,而失去一个城市并不改变其他城市之间的连通性,则不要发出警报。


输入格式:

输入在第一行给出两个整数N(0 < N ≤ 500)和M(≤ 5000),分别为城市个数(于是默认城市从0到N-1编号)和连接两城市的通路条数。随后M行,每行给出一条通路所连接的两个城市的编号,其间以1个空格分隔。在城市信息之后给出被攻占的信息,即一个正整数K和随后的K个被攻占的城市的编号。


注意:输入保证给出的被攻占的城市编号都是合法的且无重复,但并不保证给出的通路没有重复。


输出格式:

对每个被攻占的城市,如果它会改变整个国家的连通性,则输出Red Alert: City k is lost!,其中k是该城市的编号;否则只输出City k is lost.即可。如果该国失去了最后一个城市,则增加一行输出Game Over.


输入样例:

1. 5 4
2. 0 1
3. 1 3
4. 3 0
5. 0 4
6. 5
7. 1 2 0 4 3

结尾无空行


输出样例:

1. City 1 is lost.
2. City 2 is lost.
3. Red Alert: City 0 is lost!
4. City 4 is lost.
5. City 3 is lost.
6. Game Over.

结尾无空行


题意:失去一个城市并不改变其他城市之间的连通性,不要发出警报,说明最少联通分量要变化2才发出警报

#include<iostream>
using namespace std;
const int N=510;
int p[N],g[N][N];
int find(int x)
{
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++) p[i]=i;//初始化
    while(m--)
    {
        int a,b;
        cin>>a>>b;
        p[find(a)]=find(b);
        g[a][b]=g[b][a]=1;//标记
    }
    int k,x,cnt1=0;//cnt1记录攻占前的连通分量个数
    for(int i=0;i<n;i++)
        if(find(i)==i) cnt1++;
    cin>>k;
    while(k--)
    {
        int cnt2=0;//cnt2记录攻占后的连通分量个数
        cin>>x;
        for(int i=0;i<n;i++)
            g[x][i]=g[i][x]=0;//攻占之后取消标记
        for(int i=0;i<n;i++) p[i]=i;//重新初始化
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if(g[i][j]) p[find(i)]=find(j);
        for(int i=0; i<n;i++)
            if(find(i)==i) cnt2++;
        if(cnt2-cnt1>1) printf("Red Alert: City %d is lost!\n",x);
        else printf("City %d is lost.\n",x);
        cnt1=cnt2;//更新攻占前的连通分量
    }
    if(cnt1==n) cout<<"Game Over.";//表示全部不连通
    return 0;
}


目录
相关文章
|
2月前
|
测试技术
【动态规划】【组合数学】1866. 恰有 K 根木棍可以看到的排列数目
【动态规划】【组合数学】1866. 恰有 K 根木棍可以看到的排列数目
|
1月前
|
存储 算法
算法训练,牛客.判断是不是平衡二叉树 牛客.最大子矩阵两个数组的交集牛客.数组中两个字符串的最小距离
算法训练,牛客.判断是不是平衡二叉树 牛客.最大子矩阵两个数组的交集牛客.数组中两个字符串的最小距离
算法训练,牛客.判断是不是平衡二叉树 牛客.最大子矩阵两个数组的交集牛客.数组中两个字符串的最小距离
|
17天前
|
算法 C++
【洛谷 P1090】[NOIP2004 提高组] 合并果子(贪心算法+哈夫曼编码+优先队列)
该编程题目要求设计算法,将不同种类的果子合并成一堆,使得消耗的体力最小。给定果子种类数`n`(1至10000)和每种果子的数量,需输出合并的最小体力值。使用优先队列(最小堆),每次取出两个数量最少的果子堆合并,并更新总体力消耗。样例输入为3种果子(1, 2, 9),输出最小体力耗费为15。提供的AC代码采用C++实现,通过优先队列优化合并顺序。
14 0
|
2月前
|
机器学习/深度学习 算法 测试技术
【单调栈】LeetCode:2818操作使得分最大
【单调栈】LeetCode:2818操作使得分最大
|
2月前
|
人工智能
牛客xiao白月赛39 D(线段树维护区间)
牛客xiao白月赛39 D(线段树维护区间)
21 0
|
存储 算法 C语言
6-1 最小生成树(普里姆算法) (10分)
6-1 最小生成树(普里姆算法) (10分)
6-1 最小生成树(普里姆算法) (10分)
L3-008 喊山 (30 分)(bfs)
L3-008 喊山 (30 分)(bfs)
86 0
L3-008 喊山 (30 分)(bfs)
|
存储
L2-031 深入虎穴 (25 分)(bfs)
L2-031 深入虎穴 (25 分)(bfs)
187 0
L2-031 深入虎穴 (25 分)(bfs)
|
机器学习/深度学习 人工智能 Java
L2-010 排座位 (25 分)(并查集)
L2-010 排座位 (25 分)(并查集)
125 0