zoukankan      html  css  js  c++  java
  • 图论——生成树

    Tyvj 3737 逐个击破

    描述

    三大战役的平津战场上,傅作义集团在以北平、天津为中心,东起唐山西至张家口的铁路线上摆起子一字长蛇阵,并企图在溃败时从海上南逃或向西逃窜。为了就地歼敌不让其逃走,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
     
    思路:
    破坏的最少=留下的最多,最大生成树,使最多一个敌军驻地包含在内
    代码:
     1 #include<iostream>
     2 #include<algorithm>
     3 #define mx 100005
     4 using namespace std;
     5 struct edge{
     6        int u;
     7        int v;
     8        long long w;
     9 };
    10 int n,k,j[mx],vis[mx],pre[mx],fa,fb;
    11 edge g[mx],tmp;
    12 int findf(int x){
    13      int t = x,k,r,sign = 0;
    14      while(x != pre[x]) x = pre[x];
    15      r = x;
    16      if(j[r]) sign = 1;
    17      while(t != r){
    18               j[t] = sign;
    19              k = pre[t];
    20              pre[t] = r;
    21              t = k;
    22      }
    23      return r;
    24 }
    25 bool cmp(edge a,edge b){
    26      return a.w > b.w;
    27 }
    28 int main(){
    29     cin>>n>>k;
    30     long long u,v,w,ans = 0,sum = 0; 
    31     for(int i = 1;i <= k;i++){
    32             cin>>u;
    33             j[u] = 1;
    34     }
    35     for(int i = 1;i < n;i++){
    36             cin>>u>>v>>w;
    37             sum += w;
    38             tmp.u = u;
    39             tmp.v = v;
    40             tmp.w = w;
    41             g[i] = tmp;
    42     }
    43     for(int i = 0;i <= n;i++){
    44             pre[i] = i;
    45     }
    46     sort(g+1,g+n-1,cmp);
    47 
    48     
    49     for(int i = 1;i < n;i++){
    50         fa = findf(g[i].u);
    51         fb = findf(g[i].v);
    52         if(j[fa] && j[fb]) continue;
    53         j[fb] = (j[fa] || j[fb]);
    54         pre[fa] = pre[fb];
    55         ans += g[i].w;
    56         
    57     }
    58     cout<<sum - ans<<endl;
    59     return 0;
    60 }
    View Code
     
     
  • 相关阅读:
    05 css继承性
    04 选择器权重
    03 css三种引入的方式
    02 css实现举例
    01 css介绍
    05 dl-添加定义列表
    04 ol-热门点击排行榜
    02 h1 p hr br 特殊符号
    01html简介
    函数内置方法
  • 原文地址:https://www.cnblogs.com/hyfer/p/4841805.html
Copyright © 2011-2022 走看看