`
人生难得糊涂
  • 浏览: 117368 次
社区版块
存档分类
最新评论

POJ1861-Kruskal算法

 
阅读更多

之前也写过Kruskal算法,到今天才发现 原来以前的写错了。(也不能说完全错,只是效率好低)。

 

以前忽视的地方主要有两点,一是Kruskal算法,一般先对边从小到大排好序,然后从小到大区边。

这样的话,排完序以后就只要一个循环就可以走完。

二是 并查集的路径压缩,我以前对并查集合并是遍历所有的结点对两个集合合并,

而正确的做法应该是这样

int flindfather(int a)
{
if(a==father[a])
return a;
else 
return findfather(father[a]);
}

 

而其实我们还可以进行路径压缩,这才是并查集的核心所在

只要将上面的代码改写一行,就能起到很好的效果

int flindfather(int a)
{
if(a==father[a])
return a;
else 
return father[a]=findfather(father[a]);
}

 

下面是1861的代码

#include<iostream>
#include <algorithm>
using namespace std;
#define MAXSIZE 30010
#define INF 9000100
int n,m;
int father[MAXSIZE];//并查集
int head[MAXSIZE];
int next[MAXSIZE];
int e;

struct node{
	int u;
	int v;
	int w;
};
node edge[MAXSIZE];
node medge[MAXSIZE];
int num;
int ansmax,anstot;
//判断两点是否属于同一集合
int judge(int a,int b)
{
	if(father[a]==father[b])//同一集合
		return 1;
	return 0;
}
bool cmp(node &a,node &b)
{
	return a.w<b.w;
}
int findset(int a)
{
	if(a==father[a])
		return a;
	else 
		return father[a]=findset(father[a]);
}
void kruskal()
{
	sort(edge,edge+e,cmp);
	int i,j;
	num=0;
	ansmax=anstot=0;
	for(i=0;i<2*m;i++)
		father[i]=i; //初始时 每个元素属于不同的集合
	
	for(i=0;i<2*m;i++)
	{
		if(findset(edge[i].u)!=findset(edge[i].v))//如果不属于同一集合
		{
			ansmax=ansmax>edge[i].w?ansmax:edge[i].w;
			medge[num++]=edge[i];
			int tu=edge[i].u;//将所有与v一个集合的全部并入u的集合
			int tv=edge[i].v;
			father[findset(tv)]=findset(tu);
		}
		
	}

}
void addnode(int u,int v,int w)
{
	edge[e].u=u;
	edge[e].v=v;
	edge[e].w=w;
	next[e]=head[u];
	head[u]=e++;
}
int main()
{
	//freopen("in.txt","r",stdin);
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		e=0;
		int t1=m;
		while(t1--)
		{
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			addnode(a,b,c);
			addnode(b,a,c);
		}
		kruskal();
		printf("%d\n",ansmax);
		printf("%d\n",num);
		for(int i=0;i<num;i++)
			printf("%d %d\n",medge[i].u,medge[i].v);
	}
}

 

 

 

 

 

0
0
分享到:
评论

相关推荐

    北大POJ初级-基本算法

    6. **图论算法**:包括图的遍历(深度优先搜索和广度优先搜索)、最短路径问题(Dijkstra算法、Floyd-Warshall算法)、最小生成树问题(Prim和Kruskal算法)。 7. **字符串处理**:如KMP算法、Rabin-Karp算法、...

    北大POJ初级-图算法

    5. **Prim算法和Kruskal算法**:这两种都是解决最小生成树问题的算法,适用于无权图或带权重的图。Prim算法从一个节点开始,每次添加一条最小的边,直到连接所有节点;而Kruskal算法则是按边的权重从小到大排序,...

    北大POJ中级-基本算法

    【北大POJ中级-基本算法】解题报告与AC代码详解 北京大学的在线编程平台POJ(Problem Set of Peking University)是许多编程爱好者和学习者提升算法技能的重要平台。中级算法题目通常涵盖了一些基础但重要的算法...

    POJ 分类题目

    - **定义**:包括 Prim 算法和 Kruskal 算法。 - **示例题目**: - poj1789 - poj2485 - poj1258 - poj3026 - **应用场景**:适用于构建最小成本网络、电力线路铺设等问题。 **4. 拓扑排序** - **定义**:对于...

    POJ2531-Network Saboteur

    "POJ2531-Network Saboteur.doc"可能是一个文档文件,详细解释了解题思路、算法描述或者解题过程。 详细知识点: 1. **图论基础**:此题很可能涉及到图的基本概念,如顶点、边、路径等。可能需要理解并应用深度...

    POJ 1679 练习克鲁斯卡尔kruskal 算法

    【标题】"POJ 1679 练习克鲁斯卡尔Kruskal算法" 在图论领域,克鲁斯卡尔(Kruskal)算法是一种用于解决最小生成树问题的有效方法。这个问题涉及到在一个加权无向图中找到一棵包括所有顶点的树,其边的权重之和尽...

    ACM题目分类.txt

    - **描述**:最小生成树算法包括Prim算法和Kruskal算法。 - **应用场景**:构建连接所有顶点且权重最小的生成树。 - **相关题目**: - POJ 1789 - POJ 2485 - POJ 1258 - POJ 3026 #### 3. 流网络算法 - **描述...

    POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类

    - **解释**:最小生成树算法主要包括Prim算法和Kruskal算法。 ##### (4) 拓扑排序 - **例题**:poj1094 - **解释**:拓扑排序是对有向无环图的一种排序方式,可以用来解决依赖关系的问题。 ##### (5) 匹配算法 - *...

    POJ第1861题源码POJ第1861题源码POJ第1861题源码POJ第1861题源码

    对于POJ第1861题,参赛者可能需要读取输入数据,构建一个加权图,然后应用Prim或Kruskal算法找出最小生成树,最后输出树中边的权重总和或者某种特定格式的树结构。解题过程可能涉及到错误处理、边界条件检查以及效率...

    ACM-POJ 算法训练指南

    2. **最小生成树**:Prim算法和Kruskal算法,用于构建图的最小生成树(poj1789, poj2485, poj1258, poj3026)。 3. **网络流**:Max-flow算法,用于解决最大流问题(poj1094)。 4. **拓扑排序**:解决有向无环图的...

    acm新手刷题攻略之poj

    - 最小生成树问题可以通过Prim算法或Kruskal算法来解决。 3. **最大流** - 推荐题目:[poj1094](https://vjudge.net/problem/POJ-1094) - 最大流问题通常涉及到Ford-Fulkerson算法或者Dinic算法的应用。 4. **...

    算法训练方案详解

    - **定义**: 包括Prim算法和Kruskal算法。 - **应用场景**: Prim适用于稠密图,Kruskal适用于稀疏图。 - **示例题目**: POJ 1789, POJ 2485, POJ 1258, POJ 3026 - **注意事项**: 理解两种算法的核心思想和实现...

    poj 图论 集合

    根据提供的文件信息,本文将对其中提及的几个POJ(Peking University Judge Online)平台上的图论题目进行详细的解析,并介绍解决这些问题时所使用的算法和技术。这些题目涵盖了图论中的多个核心概念,如最短路径、...

    POJ 3000-3700中的近100题AC代码

    - `3632`:可能是图的遍历(深度优先搜索DFS或广度优先搜索BFS)问题,或者是最小生成树(Kruskal's或Prim's算法)、最短路径(Dijkstra或Floyd算法)等。 3. **字符串处理**(String Manipulation): - `3682`...

    POJ中级图算法所有题目【解题报告+AC代码】

    2. **最小生成树**:Prim算法和Kruskal算法是两种常见的构建最小生成树的方法。Prim算法从一个顶点开始逐步添加边,而Kruskal算法则是按边的权重从小到大加入,确保不形成环路。 3. **拓扑排序**:对于有向无环图...

    POJ 1861 Network

    在这个问题中,由于需要先进行快速排序,Kruskal算法更为合适,因为它依赖于边的排序。Kruskal算法的基本步骤是: 1. 将所有边按权重从小到大排序。 2. 初始化一个空的边集合,表示最小生成树。 3. 按顺序遍历排序...

    经典 的POJ 分类

    - POJ 1258、POJ 3026:Kruskal算法的实际案例。 #### 字符串处理 - **题目示例**: - POJ 3349、POJ 3274:字符串匹配及Hash应用。 - POJ 2151、POJ 1840:利用Hash进行快速查询。 - POJ 2002、POJ 2503:Hash...

    ACM 新手指南 PKU 题目分类

    - **最小生成树**:主要算法有普里姆算法(Prim)和克鲁斯卡尔算法(Kruskal),用于求解无向图中的最小生成树。 - 示例题目:POJ 1789, POJ 2485, POJ 1258, POJ 3026 - **网络流**:涉及到最大流、最小割等问题,...

    poj训练计划.doc

    - 最小生成树算法:如Prim算法和Kruskal算法,用于找出图中的最小生成树,如`poj1789, poj2485`。 - 拓扑排序:适用于有向无环图,用于确定任务的执行顺序,如`poj1094`。 - 二分图的最大匹配:如匈牙利算法,...

    POJ算法题目分类

    * 最小生成树算法:最小生成树算法是指计算图的最小生成树的算法,如 prim、kruskal。 * 拓扑排序:拓扑排序是指计算图的拓扑排序的算法,如 poj1094。 * 二分图的最大匹配:二分图的最大匹配是指计算二分图的最大...

Global site tag (gtag.js) - Google Analytics