zoj 2966 Build The Electric System(MST)

没想到省赛题目会有这么裸的算法题。kruskal水过

 

#include<stdio.h>
#include<stdlib.h>
#define MAXM 62255
#define MAXN 505
typedef struct  edge{
	int u,v,w;
}edge;
edge edges[MAXM];
int parent[MAXN];
int n,m;
int i,j;
void UFset()//初始化
{
	for(i=0;i<=n;i++)
		parent[i]=-1;
}
int find(int x)//返回x的根节点s
{
	int s;
	for(s=x;parent[s]>=0;s=parent[s]);
	while(s!=x)//优化:压缩路径
	{
		int tmp=parent[x];
		parent[x]=s;
		x=tmp;
	}
	return s;
}
void Union(int R1,int R2)
{
	int r1=find(R1),r2=find(R2);
	int tmp=parent[r1]+parent[r2];
	if(parent[r1]>parent[r2])//优化:加权--把结点少的加到结点多的一边
	{
		parent[r1]=r2;
		parent[r2]=tmp;
	}
	else 
	{
		parent[r2]=r1;
		parent[r1]=tmp;
	}
}
int cmp(const void *a,const void *b)
{
	edge aa=*(const edge *)a;
	edge bb=*(const edge *)b;
	return aa.w-bb.w;
}
void Kruskal()
{
	int sumweight=0;//生成树的权值;
	int num=0;//已选用的变得数目
	int u,v;
	UFset();
	for(i=0;i<m;i++)
	{
		u=edges[i].u;v=edges[i].v;
		if(find(u)!=find(v))//不是同一个连通分量
		{
	//		printf("%d %d %d\n",u,v,edges[i].w);
			sumweight+=edges[i].w;num++;
			Union(u,v);
		}
		if(num>n-1) break;
	}
	printf("%d\n",sumweight);
}

int main()
{
	int T;
	int a,b,c;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		for(i=0;i<m;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			edges[i].u=a;
			edges[i].v=b;
			edges[i].w=c;
		}
		qsort(edges,m,sizeof(edges[0]),cmp);
		Kruskal();
	}
	//system("pause");
	return 0;
}

你可能感兴趣的:(c,优化,算法,struct,System,Build)