POJ - 1751 Highways (kruskal && prim)

https://vjudge.net/problem/POJ-1751

用kruskal的话就很简单了 直接把已有的加入到集合就行,然后对于每个遇到的新边,都输出一次

有大佬用prim写的

kruskal

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
const int N=754,M=N*N/2;
int n,m,k;
int p[N];
struct ndoe{
	double x,y;
}e[M];
struct edge{
	int u,v;
	double w;
	bool operator< (const edge W) const{
		return w<W.w;
	}
}g[M];
int find(int x)
{
	if(p[x]!=x) p[x]=find(p[x]);
	return p[x];
}
double getd(int i,int j)
{
	double x=e[i].x-e[j].x;
	double y=e[i].y-e[j].y;
	return sqrt(x*x+y*y);
}
void kruskal()
{
	sort(g,g+k);

	for(int i=0;i<k;i++)
	{
		int a=find(g[i].u),b=find(g[i].v);
		if(a!=b)
		{
			p[a]=b;
			printf("%d %d\n",g[i].u,g[i].v);
		}
	}
}
int main()
{
	while(~scanf("%d",&n))
	{
		for(int i=1;i<=n;i++)
			scanf("%lf %lf",&e[i].x,&e[i].y);

		for(int i=1;i<=n;i++) p[i]=i;
		scanf("%d",&m);
		for(int i=0;i<m;i++)
		{
			int a,b;
			scanf("%d %d",&a,&b);
			int t1=find(a),t2=find(b);
			p[t1]=t2;
		}
		
		k=0;
		for(int i=1;i<n;i++)
		{
			for(int j=i+1;j<=n;j++)
			{
				g[k].u=i;
				g[k].v=j;
				g[k].w=getd(i,j);
				k++;
			}
		}
		
		kruskal();
	}
	return 0;
}

prim

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
const int N=755,M=N*N/2;
int n,m,k;
int p[N];
double dis[N],g[N][N];
bool bk[N];
struct ndoe{
	double x,y;
}e[N];
double getd(int i,int j)
{
	double x=e[i].x-e[j].x;
	double y=e[i].y-e[j].y;
	return sqrt(x*x+y*y);
}
void prim()
{
	memset(p,0,sizeof p);
	memset(bk,false,sizeof bk);
	memset(dis,0x7f,sizeof dis);
	for(int i=0;i<n;i++)
	{
		int t=-1;
		for(int j=1;j<=n;j++)
		{
			if(!bk[j] && (t==-1 || dis[t]>dis[j]))
				t=j;
		}
		bk[t]=true;
		
		if(p[t] && dis[t]!=0) printf("%d %d\n",t,p[t]); //dis[t]=0 说明不是已有的 因为已有的已经初始化为0 
		
		for(int j=1;j<=n;j++)
			if(dis[j]>g[t][j])
			{
				dis[j]=g[t][j];
				p[j]=t;

			}	
	}
}
int main()
{
	while(~scanf("%d",&n))
	{
		for(int i=1;i<=n;i++)
			scanf("%lf %lf",&e[i].x,&e[i].y);
		
		memset(g,0x7f,sizeof g);
		for(int i=1;i<n;i++)
		{
			for(int j=i+1;j<=n;j++)
				g[j][i]=g[i][j]=getd(i,j);  //注意双向更新 
		}

		scanf("%d",&m);
		for(int i=0;i<m;i++)
		{
			int a,b;
			scanf("%d %d",&a,&b);
			g[a][b]=g[b][a]=0;
		}
		
		prim();
	}
	return 0;
}
posted @ 2021-07-26 19:17  斯文~  阅读(13)  评论(0)    收藏  举报

你好!