• zoj3659(经典并查集)


    这种思想很经典。 从最小的边选择,那么可以知道的是,在除去这条边的另外两个联通块,选其中一块中的点做为源点到另一块所得到的费用和。 如果你已经知道了这两个联通块内部选一个点时的最大费用和。那么这题就可以直接得到答案了,然后用递归思想独立的求这两块联通块。 

    但是这样不好实现。 如果再反着想, 把边从大到小放入图中然后记录每个联通块的最大值。 然后就是合并的时候选择的问题了 。 

    经典的思想,要好好记下 。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    #include <map>
    #include <queue>
    #include <sstream>
    #include <iostream>
    using namespace std;
    #define INF 0x3fffffff
    #define N 200200
    struct node
    {
        int x,y,key;
    }edge[N];
    
    int n;
    int bin[N];
    long long mx[N],cnt[N];
    
    int cmp(node t,node t1)
    {
        return t.key>t1.key;
    }
    
    int get(int x)
    {
        if(bin[x]==x) return x;
        return bin[x]=get(bin[x]);
    }
    
    int main()
    {
        //freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin);
        //freopen("C:\Users\Administrator\Desktop\in.txt","w",stdout);
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=0;i<=n;i++)
            {
                bin[i]=i;
                mx[i]=0;
                cnt[i]=1;
            }
            for(int i=1;i<n;i++)
            {
                scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].key);
            }
            sort(edge+1,edge+n,cmp);
            long long ans=0;
            for(int i=1;i<n;i++)
            {
                int x,y;
                x=edge[i].x; y=edge[i].y;
                int a,b;
                a=get(x); b=get(y);
                if(mx[a]+edge[i].key*cnt[b] > mx[b]+edge[i].key*cnt[a])
                {
                    mx[a]=mx[a]+edge[i].key*cnt[b];// 选a堆
                    ans=max(ans,mx[a]);
                    bin[b]=a;
                    cnt[a]+=cnt[b];
                }
                else
                {
                    mx[b]=mx[b]+edge[i].key*cnt[a]; //选b堆
                    ans=max(ans,mx[b]);
                    bin[a]=b;
                    cnt[b]+=cnt[a];
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    单位根反演
    安卓第十三天笔记-服务(Service)
    安卓第十二天笔记-广播
    安卓第十一天笔记-Intent与inter-filter配置
    安卓第十天笔记-fragment
    安卓第九天笔记-Activity
    安卓第八天笔记--网络编程二
    安卓第七天笔记--网络编程一
    安卓第六天笔记--ListView
    安卓第五天笔记-对话框
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/3354956.html
Copyright © 2020-2023  润新知