POJ 3625 - MST

1.Question:

題意:
輸入:n,m
n代表已經點個數,m表示有多少條邊已經連接成功
本題是一個稠密圖,每兩個點之間都有邊相連
之後的輸入的代表兩個點之間有連邊

輸出:
最小的需求,本題是一個稠密圖

2.Solution:

因爲是稠密圖,本題的Krustral沒有Prim快
本題是一個Prim的版題,但是不知道爲什麼,可能是精度的問題,導致的已知在WA
之後莫名其妙的AC
我們的已經存在的連邊,我們只要在稠密圖中優先連接就可以了

3.Code:

#include"iostream"
#include"cstdio"
#include"cstdlib"
#include"cstring"
#include"cmath"
#define INF 0x3f3f3f3f
#define N 1010

using namespace std;

typedef struct node
{
	double x,y;
}point;

double map[N][N];
double dis[N];
int n,m;
point save[N];
int book[N];

double cal(int i,int j)
{
	double vx=(save[i].x-save[j].x)*(save[i].x-save[j].x);
	double vy=(save[i].y-save[j].y)*(save[i].y-save[j].y);
	return sqrt(vx+vy+0.0);
}

double prim()
{
	memset(dis,0,sizeof(dis));
	memset(book,0,sizeof(book));
	double sum=0;
	for(int i=1;i<=n;i++)
	{
		dis[i]=map[1][i];
	}
	dis[1]=0;
	book[1]=1;
	for(int i=1;i<=n;i++)
	{
		double mink=100000000;
		int minpoint;
		for(int j=1;j<=n;j++)
		{
			if(book[j]==0&&dis[j]<mink) 
			{
				mink=dis[j];
				minpoint=j;
			}
		}
		if(mink==100000000) break;
		book[minpoint]=1;
		sum+=mink;
		for(int j=1;j<=n;j++)
		{
			if(book[j]==0&&dis[j]>map[minpoint][j])
			{
				dis[j]=map[minpoint][j];
			}
		}
	}
	return sum;
}

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		for(int j=i;j<=n;j++)
		{
			map[i][j]=100000000;
		}
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%lf%lf",&save[i].x,&save[i].y);
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		    map[i][j]=cal(i,j);
	}
	for(int i=1;i<=m;i++)
	{
		int dx,dy;
		scanf("%d%d",&dx,&dy);
		map[dx][dy]=map[dy][dx]=0;
	}
	double kk=prim();
	printf("%.2lf\n",kk);
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章