最小生成树模板

//Kruskal
#include<bits/stdc++.h>
using namespace std;
int n,c,tot,kx,ky,fx,fy,sum=0;
float ans,cx[105],cy[105],cv[105][105],f[105];
struct point
{
	int x,y;
	float v;
}d[105];
int cmp(point a,point b)
{
   return a.v<b.v;
}
int find(int x)
{
	if(f[x]!=x)
		f[x]=find(f[x]);
	return f[x];	
}
void put(int x,int y,float v)
{
	tot++;
	d[tot].x=x;
	d[tot].y=y;
	d[tot].v=v;
}
void mstKruskal()
{
	for(int i=1;i<=tot;i++)
	{
		kx=d[i].x;
		ky=d[i].y;
		fx=find(kx);
		fy=find(ky);
		if(fx!=fy)
		{
			f[fx]=fy;
			ans=ans+d[i].v;
			sum++;
			if(sum+1==n)
				return ;
		}
	}
}
int main()
{
	while(true)
	{
		scanf("%d",&n);
		if(n==0)
			break;
		ans=0;
		c=c+1;
		sum=0;
		tot=0;
		for(int i=1;i<=101;i++)
			f[i]=i;
		for(int i=1;i<=n;i++)
			scanf("%f %f",&cx[i],&cy[i]);
		for(int i=1;i<=n;i++)
			for(int j=i+1;j<=n;j++)
			{
				cv[i][j]=sqrt( (cx[i]-cx[j])*(cx[i]-cx[j]) + (cy[i]-cy[j])*(cy[i]-cy[j]));
				put(i,j,cv[i][j]);	
				cv[j][i]=cv[i][j];
			}	
		sort(d+1,d+1+tot,cmp);	
		mstKruskal();
		printf("Case #%d:\nThe minimal distance is: %.2f\n\n",c,ans);	
	}
}
//Prim
#include<bits/stdc++.h> 
using namespace std;
int n,c=0,minp;
float v[105][105],x[105],y[105],ans,d[105],minnum;
bool put[105]; 
void mstPrim()
{
	for(int i=1;i<=101;i++)
		d[i]=99999999;
	d[1]=0;
	memset(put,false,sizeof(put));
	while(true)
	{
		minnum=99999999;
		for(int i=1;i<=n;i++)
			if(put[i]==false&&d[i]<minnum)
			{
				minnum=d[i];
				minp=i;
			}
		if(minnum==99999999)
			break;
		put[minp]=true;
		ans=ans+minnum;
		for(int i=1;i<=n;i++)
			if(put[i]==false) 
				d[i]=min(d[i],v[i][minp]);	
	}
}
int main()
{
	while(true)
	{
		scanf("%d",&n);
		if(n==0)
			return 0;
		c=c+1;	
		ans=0;
		for(int i=1;i<=n;i++)
			scanf("%f %f",&x[i],&y[i]);
		for(int i=1;i<=n;i++)
			for(int j=i+1;j<=n;j++)
			{
				v[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));	
				v[j][i]=v[i][j];	
			}	
		mstPrim();
		printf("Case #%d:\nThe minimal distance is: %.2f\n\n",c,ans);
	} 
}

https://begin.lydsy.com/JudgeOnline/problem.php?id=1623

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值