[KuangBin最短路专题]POJ-2387-Til the Cows Come Home

POJ-2387-Til the Cows Come Home

原题链接:传送门

题目大意

给你一个无向图,让你求出来,从n 到 1的最短路径。

分析

这个题属于模板巩固题。

AC 代码

朴素Dijkstra

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 1005;
const int M = N * (N + 1) / 2;
int n , m;
struct edge{
	int w , next , to;
}e[M];
int head[N] , tot , dis[N] , vis[N];
void add(int a,int b,int c)
{
	e[++tot].to = b;
	e[tot].w = c;
	e[tot].next = head[a];
	head[a] = tot;
}
void dijkstra(int s)
{
	memset(dis , 0x3f , sizeof dis);
	memset(vis , 0 , sizeof vis);
	dis[s] = 0;
	for(int j = 0;j < n ;j ++)
	{
		int x = -1;
		for(int i = 1;i <= n ;i ++)
		{
			if(!vis[i] && (x == -1 || dis[i] < dis[x]))x = i;
		}
		vis[x] = 1;
		for(int i = head[x];i != -1 ;i = e[i].next)
		{
			int y = e[i].to , w = e[i].w;
			if(dis[y] > dis[x] + w)
				dis[y] = dis[x] + w;
		}
	}
}
int main()
{
	memset(head , -1 , sizeof head);
	cin >> m >> n;
	for(int i = 0;i < m ;i ++)
	{
		int a , b , c;
		cin >> a >> b >> c;
		add(a , b , c);
		add(b , a , c);
	}
	dijkstra(1);
	cout << dis[n] << endl;
	return 0;
}

堆优化的Dijkstra

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;

const int N = 1005;
const int M = N * (N + 1) / 2;
int n , m;
struct edge{
	int w , next , to;
}e[M];
int head[N] , tot , dis[N] , vis[N];
void add(int a,int b,int c)
{
	e[++tot].to = b;
	e[tot].w = c;
	e[tot].next = head[a];
	head[a] = tot;
}
struct node{
	int x , val;
	bool operator < (const node now) const{
		return val > now.val;
	}	
};
void head_dijkstra(int s)
{
	memset(dis , 0x3f , sizeof dis);
	memset(vis , 0 , sizeof vis);
	priority_queue<node> q;
	dis[s] = 0;
	q.push({s, 0});
	while(!q.empty())
	{
		int x = q.top().x;q.pop();
		if(vis[x])continue;
		vis[x] = 1;
		for(int i = head[x] ;i != -1 ;i = e[i].next)
		{
			int y = e[i].to , w = e[i].w;
			if(dis[y] > dis[x] + w)
			{
				dis[y] = dis[x] + w;
				q.push({y , dis[y]});
			}
		}
	}
}
int main()
{
	memset(head , -1 , sizeof head);
	cin >> m >> n;
	for(int i = 0;i < m ;i ++)
	{
		int a , b , c;
		cin >> a >> b >> c;
		add(a , b , c);
		add(b , a , c);
	}
	head_dijkstra(1);
	cout << dis[n] << endl;
	return 0;
}

SPFA

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;

const int N = 1005;
const int M = N * (N + 1) / 2;
int n , m;
struct edge{
	int w , next , to;
}e[M];
int head[N] , tot , dis[N] , vis[N];
void add(int a,int b,int c)
{
	e[++tot].to = b;
	e[tot].w = c;
	e[tot].next = head[a];
	head[a] = tot;
}

void spfa(int s)
{
	memset(dis , 0x3f , sizeof dis);
	memset(vis , 0 , sizeof vis);
	dis[s] = 0 , vis[s] = 1;
	queue<int> q;
	q.push(s);
	while(!q.empty())
	{
		int x = q.front(); q.pop();
		vis[x] = 0;
		for(int i = head[x] ; i != -1 ;i = e[i].next)
		{
			int y = e[i].to , w = e[i].w;
			if(dis[y] > dis[x] + w)
			{
				dis[y] = dis[x] + w;
				if(!vis[y])q.push(y) , vis[y] = 1;
			}
		}
	}
}
int main()
{
	memset(head , -1 , sizeof head);
	cin >> m >> n;
	for(int i = 0;i < m ;i ++)
	{
		int a , b , c;
		cin >> a >> b >> c;
		add(a , b , c);
		add(b , a , c);
	}
	spfa(1);
	cout << dis[n] << endl;
	return 0;
}
posted @ 2020-09-27 17:15  _starsky  阅读(131)  评论(0编辑  收藏  举报