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

poj 最小生成树 prim Kruskal 1251 1287 2396

 
阅读更多

poj1251

用的是Kruskal算法 以及并查集

#include "iostream"
using namespace  std;
#define  maxsize 110
typedef struct Edge
{
	int weight;//权值
	int  node1;//顶点
	int node2;//顶点
} Edge;

Edge e[maxsize];
int vis[maxsize];

int   putIn(int n)
{


	//输入
	char ch;
	int num;
	char ch1;
	int t;
	int i,j,k=0;
	for (i=0;i<n-1;i++)
	{
		cin>>ch>>num;
		for (j=0;j<num;j++)
		{
			cin>>ch1>>t;
			e[k].weight=t;
			e[k].node1=ch-65;
			e[k].node2=ch1-65;
			k++;
		}	
	}


	return  k;//边的个数
}

int cmp( const void *a ,const void *b)
{
	
	Edge *aa=(Edge*)a;
	Edge *bb=(Edge*)b;

	return aa->weight>bb->weight?1:-1;
}

void union_node(int i,int len)
{

	//将e[i].node1的集合并入e[i].node2的集合
	int j;
	int t=vis[e[i].node1];//要先将vis[e[i].node1保存下来 因为循环中会改变值
	for (j=0;j<len;j++)
	{
		if (vis[j]==t)
		{
			vis[j]=vis[e[i].node2];
		}
	}
}

int Kruskal(int len,int n)
{

	int i,j;
	int ans=0;

	//vis数组用做并查集
	for (i=0;i<n;i++)//i<len是错的  应该是村庄个数
	{
		vis[i]=i;//表示第i个元素属于第i个集合
	}

	
	for (i=0;i<len;i++)
	{

		if (vis[e[i].node1]!=vis[e[i].node2])//如果该边的两个顶点在不同的集合
		{
			//将两点并入一个集合
			union_node(i,len);
			//累加权值
			ans+=e[i].weight;
		}
	}

	return  ans;

}
int main()
{
	
	int n;
	int i,j;
	while(cin>>n)
	{
		
		if(n==0)
			break;
		int len=putIn(n);
	
		//按权值从小到大排序
		qsort(e,len,sizeof(e[0]),cmp);
			

		//Kruskal算法生成最小生成树
		int ans=Kruskal(len,n);
		
		//输出结果
		cout<<ans<<endl;
		
	}
	return 0;
}

 

poj 1287

 

prim 

 

#include "iostream"
using namespace  std;
#define MAXSIZE 1500
#define MAX 99999999
int map[MAXSIZE][MAXSIZE];
int vis[MAXSIZE];
int temp[MAXSIZE];
int main()
{
	int n,m;
	while (1)
	{
		scanf("%d",&n);
		if (n==0)
		{
			break;
		}
		scanf("%d",&m);

		int  ans=0;
		int i,j;
		for (i=0;i<n;i++)
		{
			for (j=0;j<n;j++)
			{
				map[i][j]=MAX;
			}
		}
		for (i=0;i<m;i++)
		{
			int t1,t2,w;
			scanf("%d%d%d",&t1,&t2,&w);
			if (w<map[t1-1][t2-1])
				map[t1-1][t2-1]=w;

		}
		for (i=0;i<m;i++)
		{
			for (j=0;j<m;j++)
			{
				if (map[i][j]<map[j][i])
				{
					map[j][i]=map[i][j];
				}
			}
		}
		memset(vis,0,sizeof(vis));
		for (j=0;j<n;j++)
		{
			temp[j]=MAX;
		}
		i=0;
		for (j=0;j<n;j++)
		{
			if (map[i][j]!=0)
				if (map[i][j]<temp[j])
				{
					temp[j]=map[i][j];
				}
		}
		vis[0]=1;
		while (i<n-1)
		{
			
			//找最小的边
			int min=MAX;
			int minindex=0;
			for (j=0;j<n;j++)
			{
				if (vis[j]==1)
				{
					continue;
				}
				if (min>temp[j])
				{
					min=temp[j];
					minindex=j;
				}
			}
			
			
			//把最小的边的顶点加入集合 
			vis[minindex]=1;
			
			//更新temp
			for (j=0;j<n;j++)
			{
				if (map[minindex][j]!=0&&vis[j]!=1)
					if (map[minindex][j]<temp[j])
					{
						temp[j]=map[minindex][j];
					}
			}
			
			
			ans+=min;
			i++;
			
			
		}
		printf("%d\n",ans);

	}
	
	return 0;	
}

 

 

poj 2395 

与1251一样

#include "iostream"
using namespace  std;
#define  maxsize 10015
typedef struct Edge
{
	int weight;//权值
	int  node1;//顶点
	int node2;//顶点
} Edge;

Edge e[maxsize];
int vis[maxsize];

void   putIn(int n,int m)
{

	int num=0;
	//输入
	for (int i=0;i<m;i++)
	{
		int  k1,k2,w;
		cin>>k1>>k2>>w;
		e[num].node1=k1;
		e[num].node2=k2;
		e[num].weight=w;
		num++;
	}

	//return  m;//边的个数
}

int cmp( const void *a ,const void *b)
{
	
	Edge *aa=(Edge*)a;
	Edge *bb=(Edge*)b;

	return aa->weight>bb->weight?1:-1;
}

void union_node(int i,int len)
{

	//将e[i].node1的集合并入e[i].node2的集合
	int j;
	int t=vis[e[i].node1];//要先将vis[e[i].node1保存下来 因为循环中会改变值
	for (j=0;j<len;j++)
	{
		if (vis[j]==t)
		{
			vis[j]=vis[e[i].node2];
		}
	}
}

int Kruskal(int m,int n)
{

	int i,j;
	int ans=0;

	//vis数组用做并查集
	for (i=0;i<n;i++)//i<len是错的  应该是村庄个数
	{
		vis[i]=i;//表示第i个元素属于第i个集合
	}

	int  count=0;
	int max=0;
	for (i=0;i<m;i++)
	{
		
		if (vis[e[i].node1]!=vis[e[i].node2])//如果该边的两个顶点在不同的集合
		{
			//将两点并入一个集合
			union_node(i,m);
			//累加权值
			ans+=e[i].weight;
			if(max<e[i].weight)
				max=e[i].weight;
			count++;
		}
		if (count==n-1)
		{
			break;
		}
	}

	return  max;

}
int main()
{
	
	int n,m;
	int i,j;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
	//	cin>>n>>m;
		//cin>>m;
		putIn(n,m);
	
		//按权值从小到大排序
		qsort(e,m,sizeof(e[0]),cmp);
			

		//Kruskal算法生成最小生成树
		int ans=Kruskal(m,n);
		
		//输出结果
		cout<<ans<<endl;
		
	}
	return 0;
}

 

 

0
0
分享到:
评论

相关推荐

    poj1251 最小生成树

    标题“poj1251 最小生成树”是一个编程竞赛题目,来源于著名的在线编程平台POJ(Programming Online Judge)。这个题目主要涉及图论中的一个经典算法问题——最小生成树(Minimum Spanning Tree, MST)。在图论中,...

    最小生成树题解1

    对于这些题目,理解最小生成树的基本算法如 Prim 和 Kruskal 是关键,同时要注意根据具体问题的特性调整算法的应用。在实际编程时,还需要注意数据结构的选择,例如使用优先队列(二叉堆)优化 Prim 算法,或者使用...

    最小生成树(MST)问题——北京大学暑期课《ACM/ICPC竞赛训练》

    构造最小生成树主要有两种经典算法:Prim算法和Kruskal算法。 **Prim算法** Prim算法是一种贪心算法,其基本思想是从某个顶点出发,逐步选择与当前已构建的生成树相连接的边中权重最小的边加入生成树中,直到生成...

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

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

    poj 2485 Highways 测试数据

    在【压缩包子文件的文件名称列表】中,"poj 2485 Highways (最小生成树)"可能是题目提供的样例输入和输出文件,用于检验自己编写的程序是否正确。这些样例通常包含了各种边界情况和特殊案例,以确保算法的鲁棒性。 ...

    Poj中的一些题目源代码

    Prim和Kruskal是两种常见的求解最小生成树的算法。在某些情况下,图可能有唯一的最小生成树,这两个实现可能分别使用了这两种方法。 4. **P3522(slimness_kruskal变式).cpp** - "slimness"通常指的是树的直径或者...

    POJ 1861 Network

    常见的求解最小生成树的算法有Prim算法和Kruskal算法。在这个问题中,由于需要先进行快速排序,Kruskal算法更为合适,因为它依赖于边的排序。Kruskal算法的基本步骤是: 1. 将所有边按权重从小到大排序。 2. 初始化...

    poj解题报告2395

    常见的求解最小生成树的算法有两种:Prim算法和Kruskal算法。从代码中可以看出,这里采用的是Kruskal算法。 #### Kruskal算法详解 Kruskal算法是一种贪心算法,其核心思想是每次选取权重最小的边加入到生成树中,...

    POJ 3026 Borg Maze解题报告

    常用的最小生成树算法有两种:Prim算法和Kruskal算法。由于本题中图的边数较多(完全图),选择Prim算法更为合适。Prim算法的基本思想是从一个顶点出发,逐步添加权值最小的边来扩展生成树,直到包含所有顶点为止。 ...

    poj2485.rar_poj2485

    总结来说,这个压缩包提供了一个使用最小生成树算法解决POJ2485题目的实例,它涉及了图论、贪心算法、C++编程和在线编程竞赛实践等多个IT领域的知识点。通过分析和学习这个解题代码,我们可以加深对最小生成树算法的...

    POJ算法题目分类

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

    ACMer需要掌握的算法讲解 (2).docx

    * 最小生成树算法:prim、kruskal、POJ1789、POJ2485、POJ1258、POJ3026 * 拓扑排序:POJ1094 * 串算法:POJ1035、POJ3080、POJ1936 * 哈希表和二分查找等高效查找法:POJ3349、POJ3274、POJ2151、POJ1840、POJ2002...

    poj题目分类

    * 最小生成树算法:例如 Prim、Kruskal,例如 poj1789、poj2485、poj1258、poj3026。 * 拓扑排序:例如 poj1094。 * 二分图的最大匹配:例如 poj3041、poj3020。 * 最大流的增广路算法:例如 poj1459、poj3436。...

    poj训练计划.doc

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

    POJ 分类题目 txt文件

    图论算法涉及图的数据结构和基于图的各种操作,如最短路径算法(Dijkstra、Bellman-Ford、Floyd)、最小生成树算法(Prim、Kruskal)。Dijkstra算法用于寻找图中两点间的最短路径,而Bellman-Ford算法可以处理带有负...

    poj各种分类

    #### 最小生成树 Prim算法和Kruskal算法分别基于贪心策略和并查集数据结构,用于在带权图中找到连接所有顶点的最小总权重的树结构。 #### 拓扑排序 适用于有向无环图,帮助分析任务依赖关系,如poj1094所示。 ####...

    poj图论题目汇总

    - **知识点**:最小生成树(MST),一种用于构造连接图中所有顶点且总权重最小的树的算法,如Prim算法或Kruskal算法。 #### 1273 Drainage Ditches - 最大流 - **知识点**:最大流算法,用于解决图中源点到汇点的...

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

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

    POJ2531-Network Saboteur

    4. **最小生成树**:如果涉及网络的基础设施,可能需要找到最小生成树(例如Kruskal's Algorithm或Prim's Algorithm),以最小化破坏成本。 5. **最短路径算法**:Dijkstra's Algorithm或Floyd-Warshall Algorithm...

    ACMer需要掌握的算法讲解.docx

    6. 最小生成树算法(prim, kruskal)(poj1789, poj2485, poj1258, poj3026) 7. 拓扑排序(poj1094) 8. 串(poj1035, poj3080, poj1936) 9. 哈希表和二分查找等高效查找法(poj3349, poj3274, POJ2151, poj1840, ...

Global site tag (gtag.js) - Google Analytics