!HDU 4313 破坏导弹攻城计划-连通图-(最小生成树变形)
2015-08-03 18:20
459 查看
题意:有n个城市,城市之间有n-1条路连接每个城市,也就是说有一个树,敌人在一些城市放了导弹,共有m个导弹,敌人想把导弹运到一起然后开战,现在给你个任务就是摧毁一些路,使任何两个导弹都不能运到一起,摧毁每条路都有相应的代价,求最小的代价。
分析:
导弹不能运到一起就是说任何两个导弹不能在一个连通图中,所以我们的任务就是用最少的代价摧毁一些路使m个导弹分别在m个连通图中。
这题是就反面,最少的代价,那么就是剩下的路的代价越大越好,这就是最大生成树,所以解题方法是:用Kruskal算法求最大生成树,用并查集来维护两个导弹不能在一个连通图中。
代码:
分析:
导弹不能运到一起就是说任何两个导弹不能在一个连通图中,所以我们的任务就是用最少的代价摧毁一些路使m个导弹分别在m个连通图中。
这题是就反面,最少的代价,那么就是剩下的路的代价越大越好,这就是最大生成树,所以解题方法是:用Kruskal算法求最大生成树,用并查集来维护两个导弹不能在一个连通图中。
代码:
#include<iostream> #include<algorithm> using namespace std; int fa[100005],n,m,t; struct node{ int x,y; long long v; }edge[100005]; int k[100005]; long long sum; bool cmp(node a,node b) { return a.v>b.v; } int find(int x) { if(fa[x]==x) return x; else return fa[x]=find(fa[x]); } void merge(int x,int y) { fa[find(x)]=find(y); } void kruskal() { for(int i=0;i<n-1;i++){ int fax=find(edge[i].x); int fay=find(edge[i].y); if(k[fax]&&k[fay]){ sum+=edge[i].v; continue; } else{ if(k[fax]||k[fay]) k[fax]=k[fay]=1; merge(fax,fay); } } } int main() { cin>>t; while(t--){ memset(k,0,sizeof(k)); cin>>n>>m; for(int i=0;i<n;i++) fa[i]=i; for(int i=0;i<n-1;i++) cin>>edge[i].x>>edge[i].y>>edge[i].v; int tmp; for(int i=0;i<m;i++){ cin>>tmp; k[tmp]=1; } sort(edge,edge+n-1,cmp); sum=0; kruskal(); cout<<sum<<endl; } }
相关文章推荐
- error: #29: expected an expression,error: #140: too many arguments in function call
- Android发送短信
- Android复习笔记(7) -发送广播
- Struts2入门+Hello Word实例
- HDU 1892(树状数组二维)
- 丢掉那些所谓的真理,来看看如何做好产品?
- python 闭包
- 不要把你的input元素设置为“action”或“submit”
- linux基础之计算机硬件
- 【算法总结】堆及堆排序总结
- 实现页面打印(JS 、JQuery)
- AAC 编解码封装
- Android复习笔记(6) -BrodCastReceiver (广播接收者
- poj3907
- 编译器变量__func__, __FILE__...
- linux中结构体对齐
- GDI绘图1——杂项
- Very cms 必备知识储备
- mycat ERROR 1064 (HY000): ReplaceStatement can't be supported
- C++面试题