题目背景
三大战役的平津战场上,傅作义集团在以北平、天津为中心,东起唐山西至张家口的铁路线上摆起子一字长蛇阵,并企图在溃败时从海上南逃或向西逃窜。为了就地歼敌不让其逃走,(被和谐了)制定了先切断敌人东西两头退路然后再逐个歼灭敌人的战略方针。秉承伟大军事家的战略思想,作为一个有智慧的军长你,遇到了一个类似的战场局面。
题目描述
现在有N个城市,其中K个被敌方军团占领了,N个城市间有N-1条公路相连,破坏其中某条公路的代价是已知的,现在,告诉你K个敌方军团所在的城市,以及所有公路破坏的代价,请你算出花费最少的代价将这K个地方军团互相隔离开,以便第二步逐个击破敌人。
输入输出格式
输入格式:
第一行包含两个正整数n和k。
第二行包含k个整数,表示哪个城市别敌军占领。
接下来n-1行,每行包含三个正整数a,b,c,表示从a城市到b城市有一条公路,以及破坏的代价c。城市的编号从0开始。
输出格式:
输出一行一个整数,表示最少花费的代价。
说明
【数据范围】
10%的数据:2≤n≤10;
100%的数据:2≤n≤100000,2≤k≤n,1≤c≤1000000。
代码
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int maxn=100000+5; template<class T> inline void read(T &x){ x=0;char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} } int n,k,x,u,v,c; ll ans; int father[maxn]; bool vis[maxn]; struct node{ int x,y,c; bool operator < (const node &j) const { return c>j.c; } }e[maxn]; int find(int x){ if(x!=father[x]) father[x]=find(father[x]); return father[x]; } int main(){ read(n);read(k); for(int i=1;i<=k;++i) read(x),vis[x]=1; for(int i=1;i<=n;++i) father[i]=i; for(int i=1;i<n;++i){ read(e[i].x);read(e[i].y);read(e[i].c); } sort(e+1,e+n+1); for(int i=1;i<n;++i){ int r1=find(e[i].x),r2=find(e[i].y); if(r1!=r2){ if(vis[r1]&&vis[r2]) ans+=e[i].c; else if(vis[r1]&&!vis[r2]) father[r2]=r1; else if(!vis[r1]&&vis[r2]) father[r1]=r2; else father[r1]=r2; } } printf("%lld",ans); return 0; }