(prim kruskal)【HDU 1102】Constructing Roads

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102

模板题。题意是有N个村子,给出每个村子之间的距离。有些路已经修好了,有些没有。求使每个村子都能互通马路最少还需修多少距离的路。换个说法就是求最小生成树,不过有些点或者边已经加到集合里去了。

kruskal算法:

/*
* @Author: Samson
* @Date:   2018-06-13 17:35:19
* @Last Modified by:   Samson
* @Last Modified time: 2018-06-13 21:36:51
*/
//   @URL : http://acm.hdu.edu.cn/showproblem.php?pid=1102
#include<bits/stdc++.h>
#include<algorithm>
#include <cstdlib>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int MAXN = 1e4+10;

struct node
{
	int u,v,w;
}e[MAXN];
int f[110];

bool cmp(node a,node b)
{
	return a.w<b.w;
}

int find(int x)
{
	return x==f[x]?x:f[x] = find(f[x]);
}

int kruskal(int n,int num)
{
	sort(e+1,e+1+num,cmp);
	int sum = 0,cnt = 0;
	for(int i = 1; i <= num; ++i) 
	{
		int x = e[i].u,y = e[i].v;
		x = find(x),	y = find(y);
		if(x != y)
		{
			sum += e[i].w;
			f[y] = x;
			++cnt;
		}
		if(cnt == n-1)	break; //优化,如果所有点都已经在集合里就终止循环
	}
	return sum;
}

int main(void)
{
	ios::sync_with_stdio(false); 
	//cin.tie(0);
	int n;
	while(cin>>n)
	{
		int k,cnt = 0;
		for(int i = 1; i <= n; ++i)
		{
			for(int j = 1; j <= n; ++j)
			{
				cin>>k;
				if(i >= j)	continue;
				e[++cnt].u = i,	e[cnt].v = j,	e[cnt].w = k;
			}
		}
		for(int i = 1; i <= n; ++i)
			f[i] = i;
		int q,x,y;
		cin>>q;
		while(q--)
		{
			cin>>x>>y;
			x = find(x),	y = find(y);
			f[x] = y;
		}
		cout<<kruskal(n,cnt)<<'\n';
	}
	return 0;
}


Prim做法:

/*
* @Author: Samson
* @Date:   2018-06-13 21:37:30
* @Last Modified by:   Samson
* @Last Modified time: 2018-06-13 21:59:59
*/
//   @URL : http://acm.hdu.edu.cn/showproblem.php?pid=1102
#include<bits/stdc++.h>
#include<algorithm>
#include <cstdlib>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int MAXN = 1e4+10;

struct node
{
	int u,v,w;
}e[MAXN];
int f[110],color[110],d[110],p[110],a[110][110],n;


int prim()
{
	int minv,u;
	d[1] = 0;
	while(1)
	{
		minv = INF;
		u = -1;
		for(int i = 1; i <= n; ++i)
		{
			if(minv > d[i] && !color[i])
			{
				minv = d[i];
				u = i;
			}
		}
		if(u == -1)	break;
		color[u] = 1;
		for(int v = 1; v <= n; ++v)
		{
			if(!color[v])
			{
				if(d[v] > a[u][v])
				{
					d[v] = a[u][v];
					p[v] = u;
				}
			}
		}
	}
	int sum = 0;
	for(int i = 1; i <= n; ++i)
	{
		if(p[i] != -1)
			sum += a[i][p[i]];
	}
	return sum;
}

int main(void)
{
	ios::sync_with_stdio(false); 
	//cin.tie(0);
	while(cin>>n)
	{
		int k,cnt = 0;
		for(int i = 1; i <= n; ++i)
		{
			for(int j = 1; j <= n; ++j)
			{
				cin>>a[i][j];
			}
		}
		for(int i = 1; i <= n; ++i)
		{
			color[i] = 0;
			p[i] = -1;
			d[i] = INF;
		}
		int q;
		cin>>q;
		while(q--)
		{
			int u,v;
			cin>>u>>v;
			a[u][v] = a[v][u] = 0;
		}
		cout<< prim() <<'\n';
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/suiguia/article/details/80686174