题目链接:http://poj.org/problem?id=3255
题目大意:n个点,m条边,求1号点到n号点的次短路。
分析:继续用dijkstra求。dis[ ]数组表示最短路,dis2[ ]数组表示次短路,当有一个距离d2,介于dis和dis2之间时,更新次短路距离。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define inf 0x3f3f3f3f
const int N = 200010;
int n, m, cnt, head[N], dis[5005], dis2[5005];
struct Edge{
int to, nxt, w;
}edge[N];
struct node{
int id, w;
node(){}
node(int id, int w)
{
this->id = id;
this->w = w;
}
};
bool operator < (const node a, const node b)
{
return a.w > b.w;
}
void add(int a, int b, int w)
{
edge[cnt].to = b;
edge[cnt].w = w;
edge[cnt].nxt = head[a];
head[a] = cnt++;
}
void dijkstra()
{
priority_queue<node> q;
node tmp;
q.push(node(1, 0));
memset(dis, inf, sizeof dis);
memset(dis2, inf, sizeof dis2);
dis[1] = 0;
while(!q.empty())
{
tmp = q.top();
q.pop();
int num = tmp.id;
int d = tmp.w;
if(dis2[num] < d) continue;//不是最短路,也不是次短路,忽略
for(int i = head[num]; i != -1; i = edge[i].nxt)
{
int j = edge[i].to;
int d2 = d + edge[i].w;
if(dis[j] > d2)//更新最短路
{
swap(dis[j], d2);
q.push(node(j, dis[j]));
}
if(dis[j] < d2 && d2 < dis2[j])//跟新次短路
{
dis2[j] = d2;
q.push(node(j, dis2[j]));
}
}
}
}
int main()
{
while(~scanf("%d %d", &n, &m))
{
cnt = 0;
memset(head, -1, sizeof head);
while(m--)
{
int a, b, w;
scanf("%d %d %d", &a, &b, &w);
add(a, b, w);
add(b, a, w);
}
dijkstra();
printf("%d\n", dis2[n]);
}
return 0;
}