POJ3255 Dijkstra求次短路

题目大意:给n个点R条边,求1-n的次短路。

解题思路:要求到点v次短路,有两种可能:

1,某个顶点u的最短路 + u->v

2,u的次短路 + u->v

所以我们对于每一个点更新的时候,把它的次短路记录下来,也压进堆来更新就好了。

具体怎么实现倒是一个比较巧的方法:原来更新是dist[e.to] = d2,现在是swap(dist[e.to], d2),这样d2就直接成了当前更新的前一个距离,后面更新dist2的时候直接用就可以了,不需要另开变量。

还有一个小细节就是dist1[1] = 0,dist2[1] = inf,就不说了.

AC Code:

//My Conquest Is the Sea of Stars.
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define gcd __gcd
#define pb push_back
#define mp make_pair
#define lowbit(x) x & (-x)
#define PII  pair<int, int> 
#define all(x) x.begin(), x.end()
#define rep(i, a, b) for(int i = a; i <= (b); i++)
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = (int)1e9 + 7;
const int maxn = (int)5e3 + 5;
const int maxm = (int)5205;
using namespace std;

struct edge{
	int to, cost;
	edge(){}
	edge(int to_, int cost_){
		to = to_, cost = cost_;
	}
};

vector<edge> G[maxn];

int dist[maxn], dist2[maxn];
int n, m;

void dij(){
	priority_queue<PII, vector<PII>, greater<PII> > q;
	memset(dist, 0x3f, sizeof(dist));
	memset(dist2, 0x3f, sizeof(dist2));
	dist[1] = 0;
	q.push(PII(0, 1));
	while(!q.empty()){
		PII p = q.top(); q.pop();
		int v = p.se, d = p.fi;
		if(dist2[v] < d) continue;
		int len = G[v].size();
		rep(i, 0, len - 1){
			edge &e = G[v][i];
			int d2 = d + e.cost;
			if(dist[e.to] > d2){
				swap(dist[e.to], d2);
				q.push(PII(dist[e.to], e.to));
			}
			if(dist2[e.to] > d2 && dist[e.to] < d2){
				dist2[e.to] = d2;
				q.push(PII(dist2[e.to], e.to));
			}
		}
	}
}

int main()
{
	scanf("%d %d", &n, &m);
	rep(i, 1, m){
		int u, v, w; scanf("%d %d %d", &u, &v, &w);
		G[u].pb(edge(v, w));
		G[v].pb(edge(u, w));
	}
	dij();
	printf("%d\n", dist2[n]);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值