swust 1813 最小生成树 kruskal 并查集
主要参考出处:http://clemily.blog.163.com/blog/static/1680500342011431102234244/
感谢他(她)的优秀文章。我是参考学习的。
SWUST OJ 1813 灾后城市道路规划问题
Description
2008年5月12日的汶川地震给绵阳带来重大的损失,在全国人名的努力下,经过近三年的灾后重建。灾区的生活终于又恢复了平静,美丽的汶川有出现在了世人的面前,但是随着经济的恢复,绵阳的交通出现了很大的问题,特别是灾区的交通。以前留下的一些旧的公路和现在新修的一些公路错杂交错。让人们的出行很不方面。作为绵阳道路规划的负责人,Bearboy,想要找西科大的你来帮他解决这个交通问题:在整个交通网络中,去掉一些不必要的公路,以节省开支,同时保证交通的畅通,也就是,在去掉一些公路的同时,任然能够保证任意两个地点之间能够正常的交通,而且使去掉的公路长度总和最大。
Input
输入包括多组测试数据,输入(0 0)时结束。
每组测试数据,第一行为两个整数N,M。N表示地点个数(N<=3000),M表示这个N个地点之间的公路条数(M<=((N(N+1))/2))。接下来是M行,每行有三个整数St,En,Len。表示地点St和地点En之间的公路长度是Len。(可以认为在去掉公路之前所有的点都是连通的)
Output
对于每组测试数据,输出在去掉一些公路之后剩下的交通的公路总长度。
Sample Input
7 12
1 2 8
1 3 5
2 3 10
2 4 2
3 4 3
2 5 18
3 6 16
4 5 12
4 6 30
4 7 14
5 7 4
7 6 26
0 0
Sample Output
42
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#define max 3005
using namespace std;
int father[max];
int pointNum,pathNum;
int ans=0,point=1,paths=0;
struct node{
int from;
int to;
int len;
}tree[max*(max-1)/2];
void make_set(){
for(int i=1;i<=pointNum;i++){
father[i]=i;
}
}
bool cmp(node a,node b){
return a.len<b.len;
}
int find_set(int x){
if(x!=father[x]){
father[x]=find_set(father[x]);
}
return father[x];
}
void Union(int x,int y){
x=find_set(x);
y=find_set(y);
if(x==y) return;
father[y]=x;
ans+=tree[paths].len;
point++; //Record the num of point
}
int kruskal(){
make_set();
while(point<pointNum && paths<pathNum){ //when the point equal to the pointNum,end the while.
int st=tree[paths].from;
int en=tree[paths].to;
Union(st,en);
paths++;
}
if(point!=pointNum)
ans=-1;
return ans;
}
int main()
{
freopen("acm.txt","r",stdin);
cin>>pointNum>>pathNum;
while(pointNum){
for(int i=0;i<pathNum;i++){
cin>>tree[i].from>>tree[i].to>>tree[i].len;
}
sort(tree,tree+pathNum,cmp);
cout << kruskal()<< endl;
cin>>pointNum>>pathNum;
}
return 0;
}
acm.txt:
7 12
1 2 8
1 3 5
2 3 10
2 4 2
3 4 3
2 5 18
3 6 16
4 5 12
4 6 30
4 7 14
5 7 4
7 6 26
0 0