Destroy Walls

来源:互联网 发布:坎贝尔 阿森纳 数据 编辑:程序博客网 时间:2024/05/16 05:02

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;}
原创粉丝点击