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

    描述

    三大战役的平津战场上,傅作义集团在以北平、天津为中心,东起唐山西至张家口的铁路线上摆起子一字长蛇阵,并企图在溃败时从海上南逃或向西逃窜。为了就地歼敌不让其逃走,mzd制定了先切断敌人东洒两头退路然后再逐个歼灭敌人的战略方针。

    秉承伟大军事家的战略思想,作为一个有智慧的军长你,遇到了一个类似的战场局面:

    现在有N个城市,其中K个被敌方军团占领了,N个城市间有N-1条公路相连,破坏其中某条公路的代价是已知的,现在,告诉你K个敌方军团所在的城市,以及所有公路破坏的代价,请你算出花费最少的代价将这K个地方军团互相隔离开,以便第二步逐个击破敌人。

    输入格式

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

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

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

    城市的编号从0开始计数。

    其中:

    2<=n<=100000

    2<=k<=n

    1<=c<=1000000

    输出格式

    包含一个整数,表示最少花费的代价。

    测试样例1

    输入

    3 3 
    0 1 2 
    0 1 1 
    1 2 2

    输出

    3

    测试样例2

    输入

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

    输出

    4
     
    思路:
    破坏的最少=留下的最多,最大生成树,使最多一个敌军驻地包含在内
    代码:
    #include<iostream>
    #include<algorithm>
    #define mx 100005
    using namespace std;
    struct edge{
           int u;
           int v;
           long long w;
    };
    int n,k,j[mx],vis[mx],pre[mx],fa,fb;
    edge g[mx],tmp;
    int findf(int x){
         int t = x,k,r,sign = 0;
         while(x != pre[x]) x = pre[x];
         r = x;
         if(j[r]) sign = 1;
         while(t != r){
                  j[t] = sign;
                 k = pre[t];
                 pre[t] = r;
                 t = k;
         }
         return r;
    }
    bool cmp(edge a,edge b){
         return a.w > b.w;
    }
    int main(){
        cin>>n>>k;
        long long u,v,w,ans = 0,sum = 0; 
        for(int i = 1;i <= k;i++){
                cin>>u;
                j[u] = 1;
        }
        for(int i = 1;i < n;i++){
                cin>>u>>v>>w;
                sum += w;
                tmp.u = u;
                tmp.v = v;
                tmp.w = w;
                g[i] = tmp;
        }
        for(int i = 0;i <= n;i++){
                pre[i] = i;
        }
        sort(g+1,g+n-1,cmp);
    
        
        for(int i = 1;i < n;i++){
            fa = findf(g[i].u);
            fb = findf(g[i].v);
            if(j[fa] && j[fb]) continue;
            j[fb] = (j[fa] || j[fb]);
            pre[fa] = pre[fb];
            ans += g[i].w;
            
        }
        cout<<sum - ans<<endl;
        return 0;
    }
  • 相关阅读:
    UVA 11174 Stand in a Line,UVA 1436 Counting heaps —— (组合数的好题)
    UVA 1393 Highways,UVA 12075 Counting Triangles —— (组合数,dp)
    【Same Tree】cpp
    【Recover Binary Search Tree】cpp
    【Binary Tree Zigzag Level Order Traversal】cpp
    【Binary Tree Level Order Traversal II 】cpp
    【Binary Tree Level Order Traversal】cpp
    【Binary Tree Post order Traversal】cpp
    【Binary Tree Inorder Traversal】cpp
    【Binary Tree Preorder Traversal】cpp
  • 原文地址:https://www.cnblogs.com/hyfer/p/5812601.html
Copyright © 2011-2022 走看看