1. 程式人生 > >最小生成樹模板(kruskal和prim)

最小生成樹模板(kruskal和prim)

不知道是kruskal和prim哪個快,HDU上的prim還是比較快。

上模板:

這個是prim的

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int vis[maxn];
int n,m;
struct node
{
	int to;
	int cost;
	bool operator<(const node &a)const
	{
		return cost>a.cost;
	}
};
vector<node> G[maxn];
int prim()
{
	priority_queue<node> q;
	int ans = 0;
	vis[1] = 1;
	for(int i=0;i<G[1].size();i++)
	{
		q.push(G[1][i]);
	}
	while(!q.empty())
	{
		node tmp = q.top();
		q.pop();
		if(vis[tmp.to]) continue;
		vis[tmp.to] = 1;
		ans += tmp.cost;
		for(int i=0;i<G[tmp.to].size();i++)
		{
			q.push(G[tmp.to][i]);
		}
	}
	return ans;
}
void init()
{
	memset(vis,0,sizeof(vis));
	for(int i=0;i<maxn;i++)
	{
		G[i].clear();
	}
}
int main()
{
	while(cin>>n>>m && n)
	{
		init();
		for(int i=1;i<=n;i++)
		{
			int x,y,z;
			cin>>x>>y>>z;
			G[x].push_back((node){y,z});
			G[y].push_back((node){x,z});
		}
		int ans = prim();
		bool found = true;
		for(int i=1;i<=m;i++)
		{
			if(!vis[i])
			{
				found = false;
				break;
			}
		}
		if(found)
		{
		 	cout<<ans<<endl; 
		}
		else
		{
			cout<<"?"<<endl;
		}
	}	 
	return 0;
}

這個是kruskal

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int p[maxn],r[maxn];
int n,m;
void init()
{
	for(int i=0;i<maxn;i++)
	{
		p[i] = i;
		r[i] = 0;
	}
}
int find(int x)
{
	if(x==p[x])
	{
		return x;
	}
	return p[x] = find(p[x]);
}
void unite(int x,int y)
{
	x = find(x);
	y = find(y);
	if(x==y) return;
	if(r[x]<r[y])
	{
		p[x] = y;
	}
	else
	{
		p[y] = x;
		if(r[x]==r[y])
		{
			r[x]++;
		}
	}
}
bool same(int x,int y)
{
	return find(x)==find(y);
}
struct node
{
	int from;
	int to;
	int cost;
}q[maxn];
bool cmp(node a,node b)
{
	return a.cost<b.cost;
}
int kruskal()
{
	int ans = 0;
	sort(q+1,q+1+n,cmp);
	for(int i=1;i<=n;i++)
	{
		if(same(q[i].from,q[i].to)) continue;
		unite(q[i].from,q[i].to);
		ans += q[i].cost;
	}
	return ans;
}
int main()
{
	while(cin>>n>>m && n)
	{
		for(int i=1;i<=n;i++)
		{
			cin>>q[i].from>>q[i].to>>q[i].cost;
		}
		init();
		int ans = kruskal();
		bool found = true;
		for(int i=1;i<=m;i++)
		{
			if(!same(1,i))
			{
				found = false;
				break;
			}
		}
		if(found)
		{
			cout<<ans<<endl;
		}
		else
		{
			cout<<"?"<<endl;
		}
	}
	return 0;
}

但是感覺kruskal優美一點啊!!!