zoukankan      html  css  js  c++  java
  • LuoguP2700逐个击破【并查集/生成树/正难则反】By cellur925

    题目传送门

    题目大意:给你一棵树,求把其中k个点相互隔离(不连通)所需要的边权代价。


    这题我开始是想要求出把k个点联通的最小代价的,但后来发现还是实现起来比较困难,题解里貌似也没有这种做法,于是就鸽了。但是大体的思考方向还是不直接去想把k个点隔离,而是把问题转化。

    花费最小代价删边->花费最大代价建边。而建边的时候如果遇到一条两边都是敌人的边,我们显然是不需要建的,所以这其实我们需要维护敌人的网络,用并查集来维护。

    首先我们标记敌人点,再把边从大到小排序。枚举所有的边,如果它两端点都是敌人,那肯定不连他。如果两端点有一个是敌人,也连上,并在那个无辜的点上打一个标记,因为之后的点也不能再连他。于是我们就可以用并查集维护。最后注意我们之后调用的都是这个集合的代表元,即getf。

    Code

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define maxn 100090
     4 
     5 using namespace std;
     6 typedef long long ll;
     7 
     8 int n,k;
     9 ll ans;
    10 int vis[maxn],fa[maxn];
    11 struct node{
    12     int to,from,val;
    13 }edge[maxn*2];
    14 
    15 bool cmp(node a,node b)
    16 {
    17     return a.val>b.val;
    18 }
    19 
    20 int getf(int x)
    21 {
    22     if(fa[x]==x) return x;
    23     return getf(fa[x]);
    24 }
    25 
    26 int main()
    27 {
    28     scanf("%d%d",&n,&k);
    29     for(int i=1;i<=k;i++)
    30     {
    31         int x=0;
    32         scanf("%d",&x);
    33         vis[x]=1;
    34     }
    35     for(int i=1;i<=n-1;i++)
    36         scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].val),ans+=edge[i].val;
    37     for(int i=1;i<=n;i++) fa[i]=i;
    38     sort(edge+1,edge+1+n-1,cmp);
    39     for(int i=1;i<=n-1;i++)
    40     {
    41         int pp=getf(edge[i].from),qq=getf(edge[i].to);
    42         if(vis[pp]&&vis[qq]) continue;
    43         ans-=edge[i].val;
    44         if(qq!=pp) fa[qq]=pp;
    45         if(vis[pp]) vis[qq]=1;
    46         else if(vis[qq]) vis[pp]=1;
    47     }
    48     printf("%lld",ans);
    49     return 0;
    50 }
    View Code
  • 相关阅读:
    转载.net泛型理解说明
    转载Repository 和Unit of work的使用说明
    libtool的工作原理
    带有通配符的字符串匹配算法-C/C++
    linux core文件机制
    grep多条件和sed合并两行
    BZOJ 3232 圈地游戏 (分数规划 + SPFA找负/正环)
    CSP2019 D1T3 树上的数 (贪心+并查集)
    CSP-S 2019 第二轮 退役记
    object-c中的int NSInteger NSUInteger NSNumber辨析
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9744089.html
Copyright © 2011-2022 走看看