HDU 6187
给定n平面点一级m条边连接这些点,问最少去掉多少条边,以及在这情况下去掉边的点权最少,使得整个图是一个连通图。
其实仔细想一下就能发现满足这个条件当且仅当这些围墙不存在环,就是剩余的边形成的只会是树或森林,所以做一遍最大生成树就好,其他的都去掉
#include<bits/stdc++.h>
using namespace std;
const int Len = 500010;
struct edge {
int u, v, w;
edge(int u = 0, int v = 0, int w = 0):u(u), v(v), w(w){}
};
edge e[Len];
int f[Len];
int cnt;
long long ans;
int u, v, w;
int n, m;
int x[Len], y[Len];
int findfather(int x) {
if (f[x] == x) return x;
return f[x] = findfather(f[x]);
}
bool cmp(const edge& p, const edge& q) {
return p.w > q.w;
}
int main() {
while(scanf("%d%d", &n, &m) != EOF) {
for (int i = 1; i <= n; i++) f[i] = i;
for (int i = 1; i <= n; i++) scanf("%d%d", x+i, y+i);
ans = 0;
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &u, &v, &w);
e[i] = edge(u,v,w);
ans += w;
}
sort(e+1, e+m+1, cmp);
//printf("%lld\n", ans);
cnt = 0;
for (int i = 1; i <= m; i++) {
int fa = findfather(e[i].u), fb = findfather(e[i].v);
if (fa != fb) {
f[fa] = fb;
cnt++;
//printf("%d %d %d\n", e[i].u, e[i].v, e[i].w);
ans -= e[i].w;
}
}
printf("%d %lld\n", m-cnt, ans);
}
return 0;
}