当前位置: 代码迷 >> 综合 >> L2-013 红色警报 (25 分) (并查集判连通性)
  详细解决方案

L2-013 红色警报 (25 分) (并查集判连通性)

热度:89   发布时间:2023-12-04 04:09:13.0

传送门

代码及其注释:

#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;
}