(2020杭電多校第2場)A-Total Eclipse
阿新 • • 發佈:2020-07-24
http://acm.hdu.edu.cn/showproblem.php?pid=6763
打的時候寫了個路徑壓縮,然後寫了個用路徑壓縮的祖先找答案,wa成sb,純nt做法;
畫圖來舉例做法:
先給了你個圖
先大小排序,從大往小連線
這個時候出現了個5,那麼該連向哪呢
由於這個集合的根必然是最小元素,但這個元素又大於5,那麼就讓5成為這個集合的根
#pragma GCC optimize(2) #include<bits/stdc++.h> #define ll long long using namespace std; double pi = acos(-1); const double eps = 1e-12; const int maxn = 1e5 + 10; const int inf = 1e9; int a[maxn], p[maxn], used[maxn]; int head[maxn], cnt = 0; struct edge { int to; int next; }e[4 * maxn]; inline void add(int from, int to) { e[++cnt] = { to,head[from] }; head[from] = cnt; } int fa[maxn], f[maxn];//f鏈式尋祖,fa並查集路徑壓縮 int anc(int x) { return x == fa[x] ? x : fa[x] = anc(fa[x]); } bool cmp(int x, int y) { return a[x] > a[y]; } int main() { int t; scanf("%d", &t); while (t--) { int n, m; scanf("%d%d", &n, &m); cnt = 0; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); p[i] = i; fa[i] = i; used[i] = head[i] = f[i] = 0; } sort(p + 1, p + 1 + n, cmp); while(m--) { int x, y; scanf("%d%d", &x, &y); add(x, y); add(y, x); } for (int i = 1; i <= n; i++) { int from = p[i]; used[from] = 1; for (int j = head[from]; j; j = e[j].next) { int to = e[j].to; if (!used[to])continue; to = anc(to); if (to == from)continue; fa[to] = f[to] = from; } } ll ans = 0; for (int i = 1; i <= n; i++) ans += a[i] - a[f[i]]; printf("%lld\n", ans); } return 0; }