您的位置:首页 > 其它

hdu 1879 继续畅通工程

2013-02-15 20:28 411 查看
跟前几题畅通工程类似,求最小生成树。当状态是已修建时,直接merge。值得注意的是得用scanf,用cin会超时。还得用路径压缩的并查集,不然也会TLE。

 

#include<iostream>
#include<algorithm>
using namespace std;//20:07

#define NUM 102
struct points
{
int start;
int end;
int w;
}pos[5050];
int set[NUM];
void init()
{
for(int i=0;i<NUM;++i)
set[i]=i;
}

int find(int x)
{
int r=x;
while(r!=set[r])
r=set[r];
return r;
}

int find2(int x)//带路径压缩的查找(非递归版)
{
int k, j, r;
r = x;
while(r != set[r])     //查找根节点
r = set[r];      //找到根节点,用r记录下
k = x;
while(k != r)             //非递归路径压缩操作
{
j = set[k];         //用j暂存set[k]的父节点
set[k] = r;        //set[x]指向根节点
k = j;                    //k移到父节点
}
return r;         //返回根节点的值
}

void merge(int x,int y)
{
int a=find2(x);
int b=find2(y);
if(a!=b)
set[a]=b;
return;
}

int cmp(struct points a,struct points b)
{
return a.w < b.w;
}

int main()
{
int n,i,m,index,x,y,weight,status,sum;
freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin);
//while(cin>>n&&n!=0){
while(scanf("%d",&n)!=EOF&&n!=0){
m=n*(n-1)/2;
index=0;
sum=0;
init();
while(m--){
cin>>x>>y>>weight>>status;
if(status==1)
merge(x,y);
else {
pos[index].start=x;
pos[index].end=y;
pos[index].w=weight;
++index;
}
}
sort(pos,pos+index,cmp);
for(i=0;i<index;++i){
if(find2(pos[i].start)!=find2(pos[i].end)){
merge(pos[i].start,pos[i].end);
sum+=pos[i].w;
}
}
//cout<<sum<<endl;
printf("%d\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDU