[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;
}