Kruskal && Prim模板

1. Kruskal(并查集模板):

/*
	Kruskal:并查集实现,记录两点和距离,按距离升序排序,O (ElogE)
*/
struct Edge	{
	int u, v, w;
	bool operator < (const Edge &r) const {
		return w < r.w;
	}
}edge[E];
sort (edge+1, edge+1+m);
if (!uf.same (x, y))	uf.Union (x, y), ans += w;

2. Prim:

O (n ^ 2):

/*
	Prim:Dijkstra思想,邻接矩阵实现,适合稠密图, O (n ^ 2)
	不连通返回-1,或返回最小生成树长度(MST)
*/
int Prim(int s)	{
	memset (vis, false, sizeof (vis));
	memset (d, INF, sizeof (d));	d[s] = 0;
	int ret = 0;
	for (int i=1; i<=n; ++i)	{
		int mn = INF, u = -1;
		for (int i=1; i<=n; ++i)	{
			if (!vis[i] && d[i] < mn)	mn = d[u=i];
		}
		if (u == -1)	return -1;
		vis[u] = true;	ret += d[u];
		for (int i=1; i<=n; ++i)	{
			if (!vis[i] && d[i] > w[u][i])	{
				d[i] = w[u][i];
			}
		}
	}
	return ret;
}

O (ElogV):

/*
	Prim:Dijkstra思想,优先队列优化,适合稀疏图,O (ElogV)
	不连通返回-1,或返回最小生成树长度(MST)
*/
int Prim(int s)	{
	memset (vis, false, sizeof (vis));
	memset (d, INF, sizeof (d));
	priority_queue<Edge> Q;
	for (int i=head[s]; ~i; i=edge[i].nex)	{
		int v = edge[i].v, w = edge[i].w;
		if (d[v] > w)	{
			d[v] = w;	Q.push (Edge (v, d[v]));
		}
	}
	vis[s] = true;	d[s] = 0;	int ret = 0;
	while (!Q.empty ())	{
		int u = Q.top ().v;	Q.pop ();
		if (vis[u])	continue;
		vis[u] = true;	ret += d[u];
		for (int i=head[u]; ~i; i=edge[i].nex)	{
			int v = edge[i].v, w = edge[i].w;
			if (!vis[v] && d[v] > w)	{
				d[v] = w;	Q.push (Edge (v, d[v]));
			}
		}
	}
	return ret;
}

  

时间: 2024-08-27 00:10:37

Kruskal && Prim模板的相关文章

最小生成树(kruskal模版 Prim模板)

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2144&cid=1186 最小生成树,最重要的是了解思想 稠密图用Prim,稀疏图用Kruskal K(每次找最小的边连接,一条边连接两个点,所以单路就可以了) 1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 int bin[110]; 5 struct node 6 { 7 int

最小生成树模板【kruskal &amp; prim】

CDOJ 1966 Kruskal 解法 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 typedef long long LL; 7 8 const int N=2002; 9 const int M=2e5+2; 10 int n,m,tot=0,num=0; 11 LL ans=

kruskal 算法模板

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2896 #include <stdio.h> #include <string.h> #include <stdlib.h> struct node { int u,v,w; }q[200001]; int bin[50001]; int n,m,ans; int cmp(const void *a,const void

UVA 10369(求第K长的边,kruskal算法模板)

Arctic Networks Time Limit: 3000 MS The Department of National Defence (DND) wishes to connect several northern outposts by a wireless network. Two different communication technologies are to be used in establishing the network: every outpost will ha

ACM:最小生成树,kruskal &amp;&amp; prim,并查集

题目: 输入顶点数目,边的数目,输入每条边的两个顶点编号还有每条边的权值,求最小生成树,输出最小生成树的权值.. 注意:prim算法适合稠密图,其时间复杂度为O(n^2),其时间复杂度与边得数目无关,而kruskal算法的时间复杂度为O(eloge)跟边的数目有关,适合稀疏图. kruskal----归并边:prim----归并点 方法一:kruskal,克鲁斯卡尔,并查集实现. #include <iostream> #include <algorithm> using name

HDU 1233 prim kruskal最小生成树模板题

A - 还是畅通工程 Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小.请计算最小的公路总长度. Input 测试输入包含若干测试

几个小模板:topology, dijkstra, spfa, floyd, kruskal, prim

1.topology: 1 #include <fstream> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <cmath> 7 #include <cstdlib> 8 9 using namespace std; 10 11 #define EPS 1e-6 12 #de

uva 10397 Connect the Campus kruskal || prim

uva上的题目总是要难一些的...总是会拐弯抹角,这道题目给出有的建筑之间已经建好了光缆,让求最小生成树,我还是比较喜欢用kruskal算法,但是这道题目肯定用prim比较快,prim复杂度是n^2,kruskal复杂度eloge. 用kruskal时需要预先用并查集处理一下已经建好的光缆,让他们属于同一个祖先: 用prim算法的时候需要把他们的边置为0,这样算sum的时候就不会加上了. 代码:(kruskal) #include<iostream> #include<cstdio>

hdu 1102 Constructing Roads(kruskal || prim)

求最小生成树,有一点点的变化,就是有的边已经给出来了,所以,最小生成树里面必须有这些边,kruskal和prim算法都可以,prim更简单一些,有一点需要注意,用克鲁斯卡尔算法的时候需要将已经存在的边预处理一下,并查集转化为同一个祖先,记得要找他们的祖先再转化.普里姆算法只需要将那些已经存在的边都初始化为0就可以了. kruskal: #include<iostream> #include<cstdlib> #include<cstring> #include<a