这道题题意就是给你一个图,一次打掉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;
}