zoukankan      html  css  js  c++  java
  • luogu P2700 逐个击破

    思维题,套路题。

    本来想在学完树形dp,开始做数据结构前刷几道水题愉悦一下身心,结果tm直接匹配了一道不用树形dp十分有意思的题

    思路:考虑题目的转化:将删除的边数最小转化为留下的权值最大,用kruskal的思想加边,如果两点都是敌人直接切,如果一方是敌人,先不管,将另一方感染为敌人。这也是拆边连通性问题的一般思路。

    code:

    #include<bits/stdc++.h>
    #define IL inline
    #define RI register int
    IL void in(int &x)
    {
        int f=1;x=0;char s=getchar();
        while(s>'9' or s<'0'){if(s=='-')f=-1;s=getchar();}
        while(s>='0' and s<='9'){x=x*10+s-'0';s=getchar();}
        x*=f;
    }
    int n,k,f[100008],tot;
    bool init[1000008];
    long long ans;
    struct cod{int u,v,w;}edge[100008];
    IL int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
    IL bool ccp(const cod&a,const cod&b){return a.w>b.w;}
    int main(void)
    {
        in(n),in(k);
        for(RI i=1;i<=n;i++)f[i]=i;
        for(RI i=1,x;i<=k;i++)in(x),init[x]=true;
        for(RI i=1;i<=n-1;i++)
            in(edge[i].u),in(edge[i].v),in(edge[i].w),ans+=edge[i].w;
        std::sort(edge+1,edge+n,ccp);
        for(RI i=1;i<=n-1;i++)
        {
            int u=edge[i].u,v=edge[i].v,w=edge[i].w;
            int fu=find(u),fv=find(v);
            if(init[fu] and init[fv])continue;
            f[fu]=fv;
            ans-=w;
        }
        printf("%lld",ans);
    }
    

    收获:有时用并查集可以解决这类连通性问题(路径压缩),还有注意题目的转化

  • 相关阅读:
    js异步编程
    gitreset
    js数据类型
    vuex报错
    个人管理系统综述
    ffmpeg第7篇:数据流选择神器map指令
    eltable多选框根据条件隐藏显示
    [域渗透内网渗透] 从 web 到域控,你未曾设想的攻击链
    宽字节第二期线下培训开始招生啦!!!
    cve20212394 weblogic反序列化漏洞分析
  • 原文地址:https://www.cnblogs.com/bullshit/p/9643135.html
Copyright © 2011-2022 走看看