zoukankan      html  css  js  c++  java
  • 【题解】逐个击破 luogu2700

    题目

    题目描述:

    现在有N个城市,其中K个被敌方军团占领了,N个城市间有N-1条公路相连,破坏其中某条公路的代价是已知的。

    现在,告诉你K个敌方军团所在的城市,以及所有公路破坏的代价,请你算出花费最少的代价将这K个地方军团互相隔离开,以便第二步逐个击破敌人。

    输入格式

    第一行包含两个正整数n和k。

    第二行包含k个整数,表示哪个城市别敌军占领。

    接下来n-1行,每行包含三个正整数a,b,c,表示从a城市到b城市有一条公路,以及破坏的代价c。城市的编号从0开始。

    输出格式

    输出一行一个整数,表示最少花费的代价。

    输入输出样例

    输入

    5 3
    1 2 4
    1 0 4
    1 3 8
    2 1 1
    2 4 3
    

    输出

    4
    

    思路

    • 贪心一下,使得两个被占领的城市不连通,并不需要将中间的普通道路全部拆光,只要选取一些和占领点相连的边。

    • 可以想到,如果一条边和另一条边相连了,那么可以将两条边视为一条边,同理推广到所有的边上,引出了并查集思想,当然也可以用 kruskal 来理解。

    • 那么对于一条边所处的并查集,如果里面已经与一个聚集地相连,那么这个并查集一
      定不能和另外一个包含与另外的聚集地相连的路径的并查集合并,对于合法的路径,每次加入的时候我们统计它的长度,因为路径合法,所以不是必须拆掉的路。

    • 最后用总长度减去这些长度就可以得到拆路的最少代价。

    • 先将边排序,保证选择到必须拆的道路时一定是花费最少的


    代码

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    
    int n,m;
    long long ans;
    int vis[100010],fa[100010];
    struct arr{
        int u,v,w;
    }e[100010];
    
    inline int read(){
        int x=0,w=1;char ch=0;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='0') w=-1,ch=getchar();
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
        return x*w;
    }
    
    int gf(int x){ return x==fa[x]?x:fa[x]=gf(fa[x]);}
    inline int cmp(arr a,arr b){ return a.w>b.w;} 
    
    int main(){
        //freopen("shiitake.in","r",stdin);
        //freopen("shiitake.out","w",stdout);
        n=read();m=read();
        for(int i=1;i<=m;i++){
         int x=read();vis[x]=1; 
        }
        for(int i=1;i<n;i++){ 
            int u=read(),v=read(),w=read(); e[i].u=u;e[i].v=v;e[i].w=w; ans+=w; 
        }
        sort(e+1,e+n,cmp);
        for(int i=1;i<=n;i++) fa[i]=i;
        for(int i=1;i<n;i++){
            int f1=gf(e[i].u);
            int f2=gf(e[i].v);
            if(!(vis[f1]&&vis[f2])){
                fa[f2]=f1;
                vis[f1]=(vis[f1]||vis[f2]);
                ans-=e[i].w;
            }
        }
        printf("%lld
    ",ans);
    }
    

     

  • 相关阅读:
    Insus Meta Utility
    The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
    Insus Binary Utility
    asp.net实现文件下载功能
    Column 'Column Name' does not belong to table Table
    程序已被编译为DLL,怎样去修改程序功能
    如何在Web网站实现搜索功能
    如何把数据流转换为二进制字符串
    Asp.net更新文件夹的文件
    如何显示中文月份
  • 原文地址:https://www.cnblogs.com/bbqub/p/7755750.html
Copyright © 2011-2022 走看看