CF745 C 並查集
阿新 • • 發佈:2017-08-29
ans space sca names using 初始 將不 並查集 bsp
並查集
由於政府不能連通
我們可以先按給出的邊建立連通塊,再將不含有政府的點全部作為一個連通塊,邊數為(n-1)*n/2
然後 貪心地將該連通塊與[含政府的、且包含點數最多的]連通塊相連,然後由於新增了一些點 所以記得要加上邊
最後減去初始邊即可
#include <bits/stdc++.h> using namespace std; const int N = 100010; int fa[N]; int siz[N]; int find(int x) { if(x != fa[x]) fa[x] = find(fa[x]); return fa[x]; } int join(int a, int b) { int x = find(a); int y = find(b); if(x != y) { fa[x] = y; siz[y] += siz[x]; return 1; } return 0; } int g[N]; int vis[N]; int sum[N]; int main() { int n, m, k; while(cin >> n >> m >> k) { int cnt = 0; for(int i = 0; i <= n; i++) fa[i] = i, siz[i] = 1; for(int i = 0; i < k; i++) scanf("%d", g + i); for(int i = 0; i < m; i++) { int x, y; scanf("%d%d", &x, &y); join(x, y); } for(int i = 0; i < k; i++) vis[find(g[i])] = 1; int ma = 0; int ans = 0; for(int i = 1; i <= n; i++) { if(find(i) == i) { if(vis[i] == 1) ma = max(ma, siz[i]); else sum[cnt++] = siz[i]; ans += ((siz[i] - 1) * siz[i]) / 2; } } for(int i = 0; i < cnt; i++) for(int j = i + 1; j < cnt; j++) ans += sum[i] * sum[j]; int t = 0; for(int i = 0; i < cnt; i++) t += sum[i]; printf("%d\n", ans + t*ma - m); } }
CF745 C 並查集