立志用最少的代码做最高效的表达


战争中保持各个城市间的连通性非常重要。本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报。注意:若该国本来就不完全连通,是分裂的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.。

输入样例:
5 4
0 1
1 3
3 0
0 4
5
1 2 0 4 3

输出样例:
City 1 is lost.
City 2 is lost.
Red Alert: City 0 is lost!
City 4 is lost.
City 3 is lost.
Game Over.


核心逻辑:若某城市被攻陷,则将其在地图上删除,若删除后的连通块数量增加,则该城市为核心城市。

技巧:设置一个del数组,代表该城市是否被攻陷,若是,则不参与计数。

解法一:DFS
建立地图,建立关联,每攻陷一个城市,就深搜一次,判断连通块数量是否增加。

解法二:并查集
建立结构体数组,存储所有边的信息,每攻陷一个城市,就重新建立一次并查集,判断连通块数量是否增加(注意是重新建立,而不是搜索或查询)。


特殊样例


解法一:DFS

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;int degree[510];        //每个节点的度数
int G[510][510];        //地图
int vis[510];           //每个节点是否出现过
int del[510];           //该节点是否被删除,置1表示被删除
int n, k;void dfs(int step) {for(int i = 0; i < n; i++) if(vis[i] == 0 && del[i]==0 && G[step][i]) {vis[i] = 1;dfs(i);}
}int main() {scanf("%d %d", &n, &k);for(int i = 0; i < k; i++) {int x, y;scanf("%d %d", &x, &y);G[x][y] = G[y][x] = 1;} //计算最初的连通块数量 int num_line = 0;             //连通块数量for(int i = 0; i < n; i++) if(vis[i] == 0) {vis[i] = 1;num_line++;dfs(i); }int m; scanf("%d", &m);for(int i1 = 0; i1 < m; i1++) {int x; scanf("%d", &x);//改进:直接判断连通性,若大了,则发出警告 //删除与该点有关的信息 for(int i = 0; i < n; i++) if(G[x][i] == 1)  G[x][i] = G[i][x] = 0;del[x] = 1;  //初始化vismemset(vis, 0, sizeof(vis)); //判断连通块数量int num_line_after = 0;for(int i = 0; i < n; i++) //如果没有遍历过,并且没被删除过 if(vis[i] == 0 && del[i]==0) {vis[i] = 1;num_line_after++;dfs(i);}//判断删除点前后的连通块数量是否相同if(num_line < num_line_after)  printf("Red Alert: City %d is lost!\n", x);else  printf("City %d is lost.\n", x);//更新连通块的数量 num_line = num_line_after;if(i1 == n-1) printf("Game Over.\n");}return 0;
}

耗时:


解法二:并查集

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;struct node{int x, y;
}edge[5005];
int pre[510];           //存放并查集
int del[510];           //该节点是否被删除,置1表示被删除
int n, k;int find(int x) {return x == pre[x] ? x : pre[x] = find(pre[x]);
}void Union(int x, int y) {int fx = find(x);int fy = find(y);if(fx != fy) pre[fx] = fy;
//  if(fx > fy) pre[fx] = fy;
//  else pre[fy] = fx;
}int main() {scanf("%d %d", &n, &k);for(int i = 0; i < n; i++) pre[i] = i; //并查集初始化 for(int i = 0; i < k; i++) {scanf("%d %d", &edge[i].x, &edge[i].y);Union(edge[i].x, edge[i].y);}int num_line_before = 0;      //攻占某城市前连通块数量 for(int i = 0; i < n; i++) if(pre[i] == i) num_line_before++;int m; scanf("%d", &m);for(int i1 = 0; i1 < m; i1++) {int x; scanf("%d", &x);del[x] = 1;for(int i = 0; i < n; i++) pre[i] = i;for(int i = 0; i < k; i++) {if(!del[edge[i].x] && !del[edge[i].y]) {Union(edge[i].x, edge[i].y);}}int num_line_after = 0;       //攻占某城市后连通块数量 for(int i = 0; i < n; i++) if(pre[i] == i && !del[i]) num_line_after++;if(num_line_after > num_line_before) printf("Red Alert: City %d is lost!\n", x);else printf("City %d is lost.\n", x);if(i1 == n-1) printf("Game Over.\n");num_line_before = num_line_after;}return 0;
}

耗时:


当你一无所有,你就没有什么可以失去        ——《泰坦尼克号》

红色警报 (25 分)【测试点分析】【两种解法】相关推荐

  1. C++学习之路 | PTA(天梯赛)—— L2-013 红色警报 (25分)(带注释)(并查集)(精简)

    L2-013 红色警报 (25分) 战争中保持各个城市间的连通性非常重要.本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报.注意:若该国本来就不完全连通, ...

  2. R7-9 红色警报 (25 分)

    R7-9 红色警报 (25 分) 战争中保持各个城市间的连通性非常重要.本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报.注意:若该国本来就不完全连通,是 ...

  3. 【CCCC】L2-013 红色警报 (25分),,并查集计算集合个数

    problem L2-013 红色警报 (25分) 战争中保持各个城市间的连通性非常重要.本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报.注意:若该国本 ...

  4. L2-013 红色警报 (25 分)

    原题链接 #include<bits/stdc++.h> using namespace std; int f[600]; int lost[600]; int n,m,a,b; vect ...

  5. 7-34 红色警报 (10 分)(结构体并查集)

    7-34 红色警报 (10 分) 战争中保持各个城市间的连通性非常重要.本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报.注意:若该国本来就不完全连通,是 ...

  6. linux显示器分屏显示命令,在Linux 命令行终端分屏的两种工具

    下面介绍两种终端分屏工具:screen和tmux 一.使用screen分屏(只能上下分屏,不能左右分屏) (1)安装工具 在ubuntu系统中使用sudo apt-get install screen ...

  7. 决策树剪枝的基本策略有预剪枝和后剪枝,请简述并分析两种剪枝策略

    1.决策树是一类常见的机器学习方法,是基于树结构进行决策的.一般的,一棵决策树包含两类结点:内部节点和叶结点,其中内部节点表示表示一个特征或属性,叶结点表示__决策结果____. 2.在决策树学习中, ...

  8. 北林oj-算法设计与分析-Line up in the canteen(两种解法,附思路)

    描述 One day, there is a kind of new delicious food from one of the windows in the canteen. All studen ...

  9. 整数拆分的两种解法(已完成)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 整数拆分 ...

最新文章

  1. 【Linux】使用xshell登陆时密码框为灰色,无法输入密码
  2. Python的22个编程技巧,Pick一下?你又知道多少呢……
  3. [hiho1159] Poker
  4. MindSpore感恩节重磅福利,华为Mate 40E送送送!
  5. 基于 LiteSpeed 的一站式 PHP 网站解决方案 LLStack V1.0-1 发布
  6. 如何快速上手 angular.js
  7. 【python】面向对象类、对象的介绍
  8. dubbo负载均衡代码分析1(leastactive策略)
  9. ZOJ 1013 Great Equipment(DP)
  10. 数据库MySQL--常见基础命令
  11. 深入浅出VMware——虚拟机暂停后生成的文件
  12. JavaScript:说看懂了就懂了闭包,看懂了,还是不懂...
  13. 深度学习之神经网络(二)
  14. SpringBoot中级篇-打包-第三方jar包
  15. 3. file、inode结构体及chardevs数组等相关知识解析
  16. 区分指针数组和数组指针
  17. 面试java回答优缺点_面试时被问“你有什么优缺点”应该怎么回答?
  18. php技术聊天室源码,PHP聊天室_WebSocket技术实战
  19. 【FL论文阅读】Communication-Efficient Learning of Deep Networks from Decentralized Data
  20. scada系统集成_企业IT系统集成之PLM、ERP、MES/MOM...

热门文章

  1. 数据结构与算法 | 归并排序
  2. Redis的内存淘汰策略问题
  3. 首发 | 中间件小姐姐直播“带货”——阿里程序员必知的插件
  4. 【专题介绍】开源与创新
  5. 赋能普通用户,面向专业级的视频内容制作技术
  6. 【LiveVideoStack线上分享】FFmpeg深度学习模块架构与代码实践
  7. 网易工业级WebRTC应用实践深度解析
  8. 腾讯技术直播间 | 零代码打造智能对话机器人
  9. linux部署Nexus OSS
  10. QT隐式调用VC开发的DLL