您的位置:首页 > 其它

POJ-3255次短路

2015-08-14 09:48 381 查看
解题思路:本题利用Dijkstra算法的原理解决。由于要求出次短路,我们需要思考Dijkstra成功求解出最短路的原理,然后再加以改进。Dijkstra算法的原理是先把所有距离设为INF,然后令dist[0]=0。每次都从已经确定了距离的顶点出发,依次更新跟它相邻的结点的最短距离,以后就不再考虑“最短距离已经确定了的顶点”。注意:我们不用考虑的是“最短距离已经确定了的顶点”。那么怎么才知道哪些顶点的最短距离已经确定了呢?可以每次都选择距离最小的那个顶点出队列,以此来保证!这就是为什么优化后的Dijkstra算法用了priority_queue的原因。明白了原理,我们来解决如何找次短路。到某个顶点v的次短路,要么是到达其他某个顶点的最短路加上u->v这条边,要么是到u的次短路再加上u->v这条边。因此对于每个顶点,我们记录的不仅仅是最短距离,还有次短的距离。接下来只要用与Dijkstra算法相同的做法,不断地更新这两个距离即可求出次短路了。

#include <vector>
#include <cstdio>
#include <queue>
#include <cstring>
#define INF 100000000
using namespace std;

const int MAX_N=5000+10;

struct edge{int to,cost;
edge(int _to, int _cost){
cost = _cost;
to=_to;
}
};
typedef pair<int, int> P;
int N,R;
vector<edge> G[MAX_N]; //图的邻接表
int dist[MAX_N]; //最短距离
int dist2[MAX_N]; //次短距离

void addedge(int a,int b, int c){
G[a].push_back(edge(b,c));
G[b].push_back(edge(a,c));
}
int  solve(){
priority_queue<P, vector<P>, greater<P> > que;
fill(dist,dist+N,INF);
fill(dist2,dist2+N,INF);
dist[0]=0;
que.push(P(0,0));
while(!que.empty()){
P p=que.top(); que.pop();
int v = p.second; int d = p.first;
if(dist2[v]<d) continue;
for(int u=0;u<G[v].size();u++){
edge e = G[v][u];
int d2 = d+e.cost;
if(dist[e.to]>d2){
swap(dist[e.to],d2);
que.push(P(dist[e.to],e.to));
}
if(dist2[e.to]>d2 && dist[e.to]<d2){
dist2[e.to]=d2;
que.push(P(dist2[e.to],e.to));
}
}
}
return dist2[N-1];
}

int main(void){
while(scanf("%d%d",&N,&R)==2){
for(int i=0;i<N;i++){
G[i].clear();
}
while(R--){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
a--;b--;
addedge(a,b,c);
}
printf("%d\n",solve());
}
return 0;
}


算法的时间复杂度同改进的Dijkstra算法O(|E|log|V|)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: