BZOJ 1232: [Usaco2008Nov]安慰奶牛cheer

题目大意:一棵树,从一个点出发遍历完所有的点,再回到起点。

没到一个点和一条边都会有话费。

题解:Krusakl重新赋值边权为边权*2+点权

代码:

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 100002
using namespace std;
int n,m,w[maxn],fa[maxn],tot,ans=0x7fffffff;
struct Edge{
    int x,y,z;
    bool operator < (const Edge &a)const{return z<a.z;}
}e[maxn];
int f(int x){
    return fa[x]==x?x:fa[x]=f(fa[x]);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&w[i]),ans=min(ans,w[i]);;
    for(int i=1;i<=m;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        e[i].x=x;e[i].y=y;e[i].z=z*2+w[x]+w[y];
    }
    sort(e+1,e+m+1);
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++){
        int fx=f(e[i].x),fy=f(e[i].y);
        if(fx!=fy){
            tot++;
            fa[fx]=fy;
            ans+=e[i].z;
        }
    }
    cout<<ans;
    return 0;
}
AC

 

posted @ 2017-10-22 11:26  ANhour  阅读(182)  评论(0编辑  收藏  举报