天梯赛 L2-013 红色警报
这道题题意就是给你一个图,一次打掉k个点,如果当前点能够使得连通块数量增加,就输出警告,其它的正常输出,最后如果k==n就输出游戏结束。可以采用并查集暴力求解也可以采用bfs求解,我这里采用的是bfs,每次打掉一个点,我们先标记该点被摧毁,如果当前点的度为0或1,就一定不会影响连通块的数量,否则就找一个该点的未被摧毁的邻接点,从这个邻接点开始bfs,把所有相邻的点全部标记为1,在判断当前摧毁点的未被摧毁的邻接点是否全被标记为1,如果有0就代表,联通块增加。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
// #define int long long
typedef long long ll;
const int N = 510;
int n,m;
vector<vector<int>> g(N);
vector<int>vt(N+1,0),st(N+1,0);
void bfs(int x){
queue<int> q;
q.push(x);
vt[x] = 1;
while(q.size()){
int tmp = q.front();
q.pop();
for(auto v : g[tmp]){
if(vt[v] || st[v]) continue;
q.push(v);
vt[v] = 1;
}
}
}
int st1[N][N];
void solve() {
cin>>n>>m;
for(int i = 1;i <= m ; i++){
int u,v;
cin>>u>>v;
if(st1[u][v] == 0){
g[u].push_back(v);
g[v].push_back(u);
st1[u][v] = st1[v][u] = 1;
}
}
int k;
cin>>k;
int cnt = 0;
for(int l = 1 ; l <= k ; l++){
int x;
cin>>x;
st[x] = 1;
if(g[x].size() == 0){
cout<<"City "<<x<<" is lost."<<endl;
}else if(g[x].size() == 1){
cout<<"City "<<x<<" is lost."<<endl;
}else{
int now = -1;
for(int i = 0; i < g[x].size() ; i++){
if(st[g[x][i]] == 0){
now = g[x][i];
break;
}
}
if(now == -1){
cout<<"City "<<x<<" is lost."<<endl;
continue;
}
for(int i = 0; i <= 505 ; i++){
vt[i] = 0;
}
bfs(now);
bool flag = 0;
for(int i = 0; i < g[x].size() ; i++){
if(vt[g[x][i]] == 0 && st[g[x][i]] == 0 && g[x][i] != now){
// cout<<g[x][i]<<" bj"<<endl;;
cout<<"Red Alert: City "<<x<<" is lost!"<<endl;
flag = 1;
break;
}
}
if(!flag){
cout<<"City "<<x<<" is lost."<<endl;
}
}
}
if(k == n){
cout<<"Game Over.";
}
}
int main() {
// ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int tt = 1;
// cin >> tt;
while (tt--) {
solve();
}
return 0;
}