码迷,mamicode.com
首页 > 其他好文 > 详细

uva 10397 Connect the Campus kruskal || prim

时间:2015-08-21 23:28:05      阅读:279      评论:0      收藏:0      [点我收藏+]

标签:

uva上的题目总是要难一些的。。。总是会拐弯抹角,这道题目给出有的建筑之间已经建好了光缆,让求最小生成树,我还是比较喜欢用kruskal算法,但是这道题目肯定用prim比较快,prim复杂度是n^2,kruskal复杂度eloge。

用kruskal时需要预先用并查集处理一下已经建好的光缆,让他们属于同一个祖先;

用prim算法的时候需要把他们的边置为0,这样算sum的时候就不会加上了。

代码:(kruskal)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<string>
#include<algorithm>
#define MAX 0x7fffffff

using namespace std;
struct node
{
	int i,j;
	double len;
}gra[640000];
int p[800],n;
int cmp(const void *a,const void *b)
{
	return ((node *)a)->len - ((node *)b)->len >0? 1 :-1;
}
int find(int x)
{
	if(x == p[x])
		return x;
	else
		return p[x] = find(p[x]);
}
int a[800],b[800];
double dist(int a,int b,int c,int d)
{
	return sqrt((a-c)*(a-c)+(b-d)*(b-d));
} 
void kruskal()
{
	int i;
	double sum = 0;
	for(i=1; i<=n*(n-1)/2; i++)
	{
		int x = find(gra[i].i);
		int y = find(gra[i].j);
		if(x != y)
		{
			sum += gra[i].len;
			p[x] = y; 
		}
	}
	//cout << sum << endl;
	printf("%.2lf\n",sum);
}
int main()
{
	int i,j,m,x,y;
	while(cin >> n)
	{
		int k = 1;
		for(i=1; i<=n; i++)
			cin >> a[i] >> b[i];
		for(i=1; i<=n-1; i++)
			for(j=i+1; j<=n; j++)
				{
					gra[k].i = i;
					gra[k].j = j;
					gra[k].len = dist(a[i],b[i],a[j],b[j]);
					k ++;
				}
		cin >> m;
		for(i=1; i<=n; i++)
			p[i] = i;
		for(i=1; i<=m; i++)
		{
			cin >> x >> y;
			int xx = find(x);
			int yy = find(y);
			if(xx != yy)
				p[xx] = yy;
		}	
		qsort(gra+1,k-1,sizeof(gra[0]),cmp);
		kruskal();
	}
	return 0;
}
代码(prim):

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<string>
#include<algorithm>
#define MAX 0x7fffffff

using namespace std;
double gra[800][800]; 
int m,n;
int visit[800];
double d[800];
int xx ;
double dist(int a,int b,int c,int d)
{
	return sqrt((a-c)*(a-c)+(b-d)*(b-d));
} 
void prim()
{
	int i,j,now;
	double sum = 0;
	double MIN;
	xx = 1;
	d[xx] = 0; visit[xx] = 1; now = xx;
	for(i=2; i<=n; i++)
	{
		for(j=1; j<=n; j++)
			if(!visit[j] && d[j] > gra[now][j])
				d[j] = gra[now][j];
		MIN = MAX;
		for(j=1; j<=n; j++)
			if(!visit[j] && MIN > d[j])
				MIN = d[now = j];
		visit[now] = 1;
		//printf("now = %d\n",now);
		//cout << MIN << endl;
		sum += MIN;
	}
	printf("%.2lf\n",sum);
}
int main()
{
	int i,j;
	int a[800],b[800];
	while(cin >> n)
	{
		for(i=1; i<=n; i++)
			cin >> a[i] >> b[i];
		for(i=1; i<=n-1; i++)
			for(j=i+1; j<=n; j++)
				gra[i][j] = gra[j][i] = dist(a[i],b[i],a[j],b[j]);
		cin >> m;
		memset(visit,0,sizeof(visit));
		for(i=1; i<=n; i++)
			d[i] = MAX;
		int x,y;
		for(i=1; i<=m; i++)
		{
			cin >> x >> y;
			gra[x][y] = gra[y][x] = 0;
		}
		prim();
	}
	return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

uva 10397 Connect the Campus kruskal || prim

标签:

原文地址:http://blog.csdn.net/sinat_22659021/article/details/47842787

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!