代码及其注释:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <sstream>
#include <iterator>
#include <map>
#include <set>
#include <stack>
#include <queue>
using namespace std;
stringstream ss;
typedef long long ll;
map<int, int> mp;
const int N = 10010;
int n,m;
int p[N], st[N];
struct Note{
int x,y;
}a[N];
int find(int x)
{
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
void merge(int x, int y)
{
int px = find(x);
int py = find(y);
if(px == py) return;
p[px] = py;
}
int main()
{
cin>>n>>m;
for(int i = 0; i<n; i++) p[i] = i;
for(int i = 0; i<m; i++)
{
cin>>a[i].x>>a[i].y;
merge(a[i].x, a[i].y);
}
int sum = 0;
for(int i = 0; i<n; i++)
{
if(p[i] == i) sum++; // 连通块的数量
}
int k;
cin>>k;
int f = 0;
if(k>=n) f = 1;
while(k -- )
{
int x, cnt = 0;
cin>>x;
st[x] = 1; // 记录被攻占的城池
// 计算更新后的连通块的数量
for(int i = 0; i<n; i++) p[i] = i;
for(int i = 0; i<m; i++)
{
if(st[a[i].x] || st[a[i].y]) continue;
merge(a[i].x, a[i].y);
}
for(int i = 0; i<n; i++)
{
if(p[i] == i) cnt++;
}
// 更新后, 若连通块不变或多一个, 只是攻占了本没有连通的城或是攻占了一个端点城不会影响整国的连通性
if(sum == cnt || sum == cnt - 1) cout<<"City "<<x<<" is lost."<<endl;
else cout<<"Red Alert: "<<"City "<<x<<" is lost!"<<endl;
sum = cnt;
}
if(f) cout<<"Game Over."<<endl;
}