没想到省赛题目会有这么裸的算法题。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;
}