• hdu4424 并查集+贪心+思维


    #include<bits/stdc++.h>
    #define MAXN 200005
    using namespace std;
    
    long long n,tot;
    long long f[MAXN],cnt[MAXN],ans[MAXN];
    struct node{
        long long from,to,cost,next,tp;
    }e[MAXN<<1]; 
    
    void init(){
        tot=0;
        memset(ans,0,sizeof(ans));
        for(int i=1;i<=n;i++)f[i]=i,cnt[i]=1;
    }
    
    void add(long long x,long long y,long long z){
        tot++;
        e[tot].from=x;
        e[tot].to=y;
        e[tot].cost=z;
    }
    
    long long found(long long x){
        if(f[x]==x)return x;
        int fa=found(f[x]);
        f[x]=fa;
        return fa;
    }
    
    bool cmp(node x,node y){
        return x.cost>y.cost;
    }
    
    int main(){
        while(scanf("%lld",&n)==1){
            init();
            for(int i=1;i<n;i++){
                long long x,y,z;
                scanf("%lld%lld%lld",&x,&y,&z);
                add(x,y,z);    
            }
            sort(e+1,e+1+tot,cmp);
            for(int i=1;i<n;i++){
                long long ff=found(e[i].from),fy=found(e[i].to);
                if(ff!=fy){
                    if(ans[fy]+cnt[ff]*e[i].cost>ans[ff]+cnt[fy]*e[i].cost)swap(ff,fy);
                    ans[ff]+=(cnt[fy]*e[i].cost);
                    cnt[ff]+=cnt[fy];
                    f[fy]=ff;
                }
            }
            cout<<ans[found(1)]<<endl;
        }
    }
    View Code

    一开始有点想法....

    .................. 

    嘛,仔细分析一下,发现可以在最小值最大哪里搞一下.....

    尝试从小到大枚举每条边....发现这样答案可以计算(就是一个分治的过程....每次选择与这条边相连的两点(怎么说呢)就是舍去一段子树....差不多了吧)

    或者贪心好像也行把....每次把节点数小的给删掉....(显然满足题目要求把....).

    然后考虑怎么解决一条边是否已经再被删掉的子树里面出现....

    直接并查集维护一下每个边左右子树的根....要删掉那一个就把它的根标记一下就好了.....但是不能路径压缩,,,,(显然把....)

    但是,,上面做法会t飞

    于是乎,再度分析...

    不如从最大值考虑?

    于是乎,,,,,,发现,一些较大边对于答案没有贡献啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    那么我们要它干嘛,直接删掉.....考虑删掉后咋办....把两个点合并呗.....

    对于没有贡献的边怎么合并都无所谓啦......

    但是对于有贡献的就要考虑,既然是要最大化答案,,,,,当然是按照可以使得答案最大的来搞(感觉自己好多废话)

    于是乎就清晰了

    1 从大到小排序

    2 然后依次合并点集....

    然后这题就结束了

    ------------------------------------------------------------------------------------------------------------------------------------------------------------

    经验:

    1 仔细分析题目啊!!!!!!!

    2 遇到难搞(会炸)的地方要考虑影藏性质

    3.不能应为感觉思考出一个假的正解(没AC)就沾沾自喜 去颓

  • 相关阅读:
    JavaScript的BOM编程,事件-第4章
    C#获取程序目录
    e3商城_day05
    第三届中国云计算用户大会笔记和心得
    Android应用源码 概览
    电脑用bat脚本给手机批量自动安装apk文件 autoInstall.bat
    网上的很多Android项目源码有用吗?Android开发注意的地方。
    Android 简历 怎么写? 月薪10K,20K+, 怎么拿到面试?
    android 职业 转行
    我的Python学习之路(2)
  • 原文地址:https://www.cnblogs.com/shatianming/p/12295900.html
Copyright © 2020-2023  润新知