http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4882

原来一个排序加并查集就可以呀  思维还是不够强呀

这里没有环,所以并查集并不是用了处理环 而是指出当前集合中最优选择点

当两个集合合并时  将两个集合的最优选择点 比较择优更新

代码及其注释:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<algorithm>

#define LL long long

using namespace std;
const int INF=0x3f3f3f3f;
const int N=200005;
struct node
{
    int l,r;
    LL d;
}mem[N];
LL ans[N];//如果为最优选择点 目前的值
LL num[N];//如果为最优选择点 目前集合的元素个数
int f[N];
bool cmp(node x,node y)
{
    return x.d>y.d;
}
int findx(int x)
{
    if(f[x]!=x)
    f[x]=findx(f[x]);
    return f[x];
}
int main()
{
    //freopen("data.txt","r",stdin);
    int n;
    while(cin>>n)
    {
        for(int i=1;i<n;++i)
        cin>>mem[i].l>>mem[i].r>>mem[i].d;
        for(int i=1;i<=n;++i)
        {f[i]=i;num[i]=1;}
        sort(mem+1,mem+n,cmp);
        memset(ans,0,sizeof(ans));
        LL MAX=0;//最优答案
        for(int i=1;i<n;++i)
        {
            int k1=findx(mem[i].l),k2=findx(mem[i].r);
            ans[k1]+=(num[k2]*mem[i].d);
            ans[k2]+=(num[k1]*mem[i].d);
            //然后择优更新
            if(ans[k1]>MAX) MAX=ans[k1];
            if(ans[k2]>MAX) MAX=ans[k2];
            if(ans[k1]>ans[k2])
            {
                num[k1]+=num[k2];
                f[k2]=k1;
            }else
            {
                num[k2]+=num[k1];
                f[k1]=k2;
            }
        }
        cout<<MAX<<endl;

    }
    return 0;
}

 

 

posted on 2012-10-22 19:18  夜->  阅读(180)  评论(0编辑  收藏  举报