HDU6187 最大生成树

对。我就将它叫作最大生成树。

做法是对图的每一个连通分量做最大生成树。不在树里的墙,就是要去掉的墙。

  1. 没有环的图的最大生成树就是它自己,所以根本就不会有什么「没有环的图做了最大生成树之后就会额外少一条边」这种无厘头的问题。当然,这样的图,最小生成树也是它自己。
  2. 这根本就不是一个计算几何的问题:坐标是废的;这题考的是拓扑的性质。国王在哪个位置也没有差,因为无论他在哪里,他总是要到整个二维平面上的每一个地方的,所以就算他在(1927,0817)也一样。

结论:

  1. 我真蠢。
  2. 短板,短板 never ends。
  3. 是时候将并查集这样的数据结构打包成类了。

代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
typedef long long ll;

struct edge{
    int from, to, cost;
    double dist;
};
edge G[200005]; int edgep;
int n,m;
int T;
bool cmp(edge a, edge b){ return a.cost>b.cost; }

int root[100005];
void init(){
    for(int i=0;i<100005;i++)root[i]=i;
}
int rootof(int x){
    return root[x]=root[x]==x?x:rootof(root[x]);
}
bool merge(int a, int b){
    int ra = rootof(a), rb = rootof(b);
    if(ra==rb)return false; // already merged.
    else root[ra]=rb;
    return true;
}    

int main() {
    while(~scanf("%d%d",&n,&m)){
        init();
        edgep=0;
        for(int i=0;i<n;i++){
            int x,y;scanf("%d%d",&x,&y);
        }
        ll res = 0;
        int cnt = 0;
        for(int i=0;i<m;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            G[edgep].from=a,G[edgep].to=b,G[edgep].cost=c;
            edgep++;
            res+=c;
        }
        sort(G,G+m,cmp);
        for(int i=0;i<m;i++){
            if(merge(G[i].from,G[i].to)){
                res-=G[i].cost;
                cnt++;
            }
        }
        printf("%d %lld\n",m-cnt,res);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/erikabeats/article/details/79478681