hdu 1233 还是畅通工程

题目实质是求最小生成树,用Kruskal算法。

一、把原始图的N个节点看成N个独立子图;

二、每次选取当前最短的边(前提操作是?),看两端是否属于不同的子图;若是,加入;否则,放弃;

三、循环操作该步骤二,直到有N1条边;

AC代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define NUM 10005
int set[NUM];

struct point
{
	int begin;
	int end;
	int dis;
}points[NUM];

int cmp(const void *a, const void *b)
{
	struct point *x=(struct point *)a;
	struct point *y=(struct point *)b;
	return x->dis - y->dis;
}

void init()
{
	for(int i=0;i<=NUM;i++){
		set[i]=i;
	}
	memset(points,0,sizeof(points));
}

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

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

int main()
{
	int n,m,i,j,a,b,val,ans;
	freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin);
	while(scanf("%d",&n)!=EOF&&n!=0){
		m=n*(n-1)/2;
		init();
		for(i=0;i<m;i++){
			scanf("%d%d%d",&a,&b,&val);
			points[i].begin=a;
			points[i].end=b;
			points[i].dis=val;
		}
		qsort(points,m,sizeof(points[0]),cmp);
		j=0;
		ans=0;
		i=0;
		for(j=0;j<m;j++){
			if(i==n-1)//当解边集为n-1条时,跳出;之前就是因为这个WA
				break;
			a=points[j].begin;
			b=points[j].end;
			if(find(a)!=find(b)){
				merge(a,b);
				ans+=points[j].dis;
				i++;
			}
			
		}
		printf("%d\n",ans);


	}

	return 0;
}



你可能感兴趣的:(hdu 1233 还是畅通工程)