简单图论-4个算法

首先阐述一下最小生成树和最短路径所解决问题的区别:

最小生成树(Minimum Spanning Tree)MST:包含原图中的所有 n 个结点,并且有保持图连通的最少的边。也就是将所有结点连通,总权值最小。Prim算法和Kruskal算法。

实例:

要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树。

最短路径:寻找图(由结点和路径组成的)中两结点之间的最短路径。主要有Dijstra、Floyd、SPFA、A*算法。

Prim

多适用于邻接矩阵,通过对点的操作,

#include<iostream>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=5010;
int mp[maxn][maxn],d[maxn],n,m;
bool vis[maxn];
int prim(int x)
{
	int min,u,cnt=0;	
	d[x]=0;
	for(int i=1; i<=n; i++)
	{
		min=INF;u=-1; 
		for(int j=1; j<=n; j++)
		{
			if(vis[j]==0&&d[j]<min)
			{
				min=d[j];
				u=j;
			}
		}
		if(u==-1) return -1;//不连通 
		cnt+=min;
		vis[u]=1;
		for(int k=1; k<=n; k++)
		{
			if(vis[k]==0&&mp[u][k]<d[k])
			{
				d[k]=mp[u][k];
			}
		}
	}
	return cnt;
}
int main(){
		cin>>n>>m;
		memset(vis,0,sizeof(vis));
		memset(d,INF,sizeof(d));
		memset(mp,INF,sizeof(mp));//转化邻接矩阵时
		for(int i=1;i<=n;i++)
			mp[i][i]=0; 
		/*for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				cin>>mp[i][j];*/
		int x,y,v;		
		for(int i=1;i<=m;i++){
			cin>>x>>y>>v;
			if(mp[x][y]>v)//确保多条边时,取最小。 
				mp[x][y]=mp[y][x]=v;			
		}
		int ans=prim(1); 
		if(ans==-1)cout<<"orz"<<endl;
		else cout<<ans<<endl;
	
	return 0;
}

有时把memset mp 为0就错了。不知道mp[i][i]=0有用没?

krual

Dijstra:

猜你喜欢

转载自blog.csdn.net/ordinarv/article/details/81100858
今日推荐