度度熊的王国战略
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/132768 K (Java/Others)
参考至此
Problem Description
度度熊国王率领着喵哈哈族的勇士,准备进攻哗啦啦族。
哗啦啦族是一个强悍的民族,里面有充满智慧的谋士,拥有无穷力量的战士。
所以这一场战争,将会十分艰难。
为了更好的进攻哗啦啦族,度度熊决定首先应该从内部瓦解哗啦啦族。
第一步就是应该使得哗啦啦族内部不能同心齐力,需要内部有间隙。
哗啦啦族一共有n个将领,他们一共有m个强关系,摧毁每一个强关系都需要一定的代价。
现在度度熊命令你需要摧毁一些强关系,使得内部的将领,不能通过这些强关系,连成一个完整的连通块,以保证战争的顺利进行。
请问最少应该付出多少的代价。
Input
本题包含若干组测试数据。
第一行两个整数n,m,表示有n个将领,m个关系。
接下来m行,每行三个整数u,v,w。表示u将领和v将领之间存在一个强关系,摧毁这个强关系需要代价w
数据范围:
2<=n<=3000
1<=m<=100000
1<=u,v<=n
1<=w<=1000
Output
对于每组测试数据,输出最小需要的代价。
Sample Input
2 1
1 2 1
3 3
1 2 5
1 2 4
2 3 3
Sample Output
1
3
思路在代码中,基本就用并查集一套找,然后求连通分量的个数,如果为1则需要进行排序
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int F[3200],sum[3200];//F为父数组,sum为该点的与其他点连接的代价
int find(int p){
if(F[p]==0)return p;
return F[p] = find(F[p]);
}
int main(){
int n,m;
while(cin>>n>>m){
int nn = n-1;
memset(F,0,sizeof(F));
memset(sum,0,sizeof(sum));
for(int i = 0;i<m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(u==v)continue;//如果uv相等,那么没有必要累加代价
sum[u]+=w;
sum[v]+=w;
int a = find(u);
int b = find(v);
if(a!=b){
F[a] = b;
//统计边个数,如果n个顶点刚好友n-1个边,那么只有一个连通分量,则需要求出最小代价.因为题目要求,所以肯定不可能有环,这样就不可能分成2个连通分量
nn--;
}
}
if(nn==0){//有一个连通分量
sort(sum+1,sum+n+1);
printf("%d\n",sum[1]);
}else if(nn>0){//有多个连通分量,则不需要分割
printf("0\n");
}
}
return 0;
}