poj2349

求生成树中s-1短的边。网上说可以用prim算法,我用的是kruskal算法,时间真的惨不忍睹,我怀疑prim会超时。

#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<string>
#include<vector>
#include<queue>
#include<list>
using namespace std;
typedef long long lld;
typedef unsigned int ud;
#define Inf INT_MAX//int最大
#define Min(x,y) (x)<(y)?(x):(y)
#define Max(x,y) (x)>(y)?(x):(y)
#define PQ priority_queue
#define Q queue
#define N 505
struct Edge
{
	int u,v;
	double w;
}edge[N*(N-1)/2];
int S,P,m;
struct Vex
{
	double x,y;
}vex[N];
int parent[N];
double mst_w[N];

void InitParent()
{
	for(int i=0;i<P;i++)
		parent[i]=-1;
}

int find(int x)
{
	return parent[x]<0 ? x : find(parent[x]);
}

void merge(int r1,int r2)
{
	if(parent[r1]>parent[r2])
	{
		parent[r1]=r2;
		parent[r2]-=parent[r1];
	}
	else
	{
		parent[r2]=r1;
		parent[r1]-=parent[r2];
	}
}

bool cmp(Edge e1,Edge e2)
{
	return e1.w<e2.w;
}

double Kruskal()
{
	sort(edge,edge+m,cmp);
	InitParent();
	int k=0;
	for(int i=0;i<m;i++)
	{
		int u=find(edge[i].u);
		int v=find(edge[i].v);
		if(u!=v)
		{
			mst_w[k++]=edge[i].w;
			merge(u,v);
			if(k==P-1)
				break;
		}
	}
	return mst_w[k-S];
}

double GetW(Vex v1,Vex v2)
{
	return sqrt((v1.x-v2.x)*(v1.x-v2.x)+(v1.y-v2.y)*(v1.y-v2.y));
}

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&S,&P);
		for(int i=0;i<P;i++)
			scanf("%lf%lf",&vex[i].x,&vex[i].y);
		m=0;
		for(int i=0;i<P;i++)
			for(int j=i;j<P;j++)
			{
				if(i==j)
					continue;
				edge[m].u=i;
				edge[m].v=j;
				edge[m++].w=GetW(vex[i],vex[j]);
			}
		printf("%.2lf\n",Kruskal());
	}
	return 0;
}

你可能感兴趣的:(算法,poj,kruskal)