zoj 3659 Conquer a New Region

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;

}

 

 

你可能感兴趣的:(new)