2018.7.30 最短路问题的几个代码详解

以HDU-2544为例:

Floyd:

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
using namespace std;
typedef long long ll;
const int maxn = 2e5+5;
const double eps = 1e-12;
const int inf = 0x3f3f3f3f;
map<int,int>::iterator it;

int n,m;
int dis[133][133]; 

int main()
{
	while(~scanf("%d %d",&n,&m)&&(n||m))
	{
		memset(dis,0x3f3f3f3f,sizeof(dis));//初始化
		for(int i = 1;i<= m;i++)
		{
			int a,b,c;
			scanf("%d %d %d",&a,&b,&c);
			dis[a][b] = dis[b][a] = c;//双向边
		}
		
		for(int k = 1;k<= n;k++)
			for(int i = 1;i<= n;i++)
				for(int j = 1;j<= n;j++)
					dis[i][j] = min(dis[i][j],dis[i][k]+dis[k][j]);//更新
		
		cout<<dis[1][n]<<endl;
	}
	
	return 0;
}

Dijkstra(N^2):

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
using namespace std;
typedef long long ll;
const int maxn = 2e5+5;
const double eps = 1e-12;
const int inf = 0x3f3f3f3f;
map<int,int>::iterator it;

int n,m;
int mp[133][133],dis[133],vis[133];

void Dijkstra(int s,int e)
{
	dis[s] = 0;
	
        for(int k = 1;k<= n;k++)
	{
		int minw = 0x3f3f3f3f,minv;
		for(int i = 1;i<= n;i++)//取最小权值点
		{
			if(vis[i]) continue;
			if(dis[i]< minw)
				minw = dis[i],minv = i;
		}
		
		vis[minv] = 1;//标记走过
		if(minv == e) break;//遇终点break
		for(int i = 1;i<= n;i++)
		{
			if(vis[i]||!mp[minv][i]) continue;
			dis[i] = min(dis[i],dis[minv]+mp[minv][i]);//更新
		}
	}
	cout<<dis[e]<<endl;
}

int main()
{
	while(~scanf("%d %d",&n,&m)&&(n||m))
	{
		memset(dis,0x3f3f3f3f,sizeof(dis));//初始化
		memset(vis,0,sizeof(vis));
		memset(mp,0,sizeof(mp));
		for(int i = 1;i<= m;i++)
		{
			int a,b,c;
			scanf("%d %d %d",&a,&b,&c);
			mp[a][b] = mp[b][a] = c;
		}
		
		Dijkstra(1,n);
	}
	
	return 0; 
}

Dijkstra(NlogN):

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
using namespace std;
typedef long long ll;
const int maxn = 2e5+5;
const double eps = 1e-12;
const int inf = 0x3f3f3f3f;
map<int,int>::iterator it;

struct edge
{
	int to;
	int w;
	int ne;
} e[maxn];

struct node
{
	int pos;
	int cost;
	node(){}//没有此构造函数不能写  node t  这样
	node(int pos,int cost):pos(pos),cost(cost){}//可以写node(pos,cost)这样
	friend bool operator < (node a,node b)//运算符重载<   先把格式记住
	{
		return a.cost> b.cost;
	}
} ;

int n,m,len;
int head[maxn],dis[maxn],vis[maxn];

void add(int u,int v,int w)//加边
{
	e[len].to = v;
	e[len].w = w;
	e[len].ne = head[u];
	head[u] = len++;
}

void Dijkstra(int sx,int ex)
{
	priority_queue<node> q;
	q.push(node(sx,0));
	dis[sx] = 0;
	
	while(!q.empty())
	{
		node now = q.top();
		q.pop();		
		
		if(vis[now.pos]) continue;
		vis[now.pos] = 1;
		if(now.pos == ex) break;
		for(int i = head[now.pos];i!= -1;i = e[i].ne)//遍历与之相连的点
		{
			int id = e[i].to;//与之相连的点
			if(dis[id]> dis[now.pos]+e[i].w)
			{
				dis[id] = dis[now.pos]+e[i].w;//更新
				q.push(node(id,dis[id]));//压入更新后的节点
			}		
		}
	}
	
	cout<<dis[ex]<<endl;
}

void init()
{
	len = 0;
	memset(dis,0x3f3f3f3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	memset(head,-1,sizeof(head));
}

int  main()
{
	while(~scanf("%d %d",&n,&m)&&(n||m))
	{
		init();//初始化
		
		for(int i = 1;i<= m;i++)
		{
			int a,b,c;
			scanf("%d %d %d",&a,&b,&c);
			add(a,b,c);add(b,a,c);
		}
		
		Dijkstra(1,n);
	}
	
	return 0;
}

还是希望大家每个题都能自己重新敲一下,反复琢磨算法的过程~

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值