您的位置:首页 > 其它

POJ3255--次短路

2015-09-01 16:16 309 查看
求1到N的次短路,到某个顶点v的次短路有两种可能,一是到其他某个顶点u的最短路+edge(u,v)二是到其他某个点u的次短路+edge(u,v);

因此在松弛的时候不仅要记录最短路,同时也要记录次短路

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
#include<string>
#include<queue>
#define INF 1e6
using namespace std;
const int maxn = 5005;
struct node
{
int d,u;
bool operator < (const node& rhs) const{
return d > rhs.d;
}
};
struct Edge
{
int from,to,dist;
Edge(int u,int v,int d):from(u),to(v),dist(d){}
};

int n,m;
vector<Edge> edges;//保存边的信息
vector<int> g[maxn];//保存的边在edges数组里的编号;
int d[maxn],d2[maxn];//最短距离,次短距离

void addedge(int from,int to,int dist)//跟刘汝佳学的。。
{
edges.push_back((Edge){from,to,dist});
edges.push_back((Edge){to,from,dist});
int k = edges.size();
g[from].push_back(k-2);
g[to].push_back(k-1);
}

void dijkstra(int s)
{
priority_queue<node> que;
for(int i = 1; i <= n; ++i){ d[i] = d2[i]= INF;}
d[s] = 0;

que.push((node){0,s});
while(!que.empty())
{
node x = que.top();que.pop();
int u = x.u;
if(d2[u] < x.d) continue;//如果次短距离比这个节点的d值还小。。说明没有更新的必要
for(int i = 0; i < g[u].size(); ++i)
{
Edge& e = edges[g[u][i]];
int p = x.d + e.dist;//待更新的值,从这个节点进行松弛操作,注意这里的x.d可能是最短距离也可能是次短距离。
if(d[e.to] > p)
{
swap(d[e.to],p);//如果最短距离比这个P还大,那么要换一换这个值;这样可以省掉一些讨论
que.push((node){d[e.to],e.to});
}
if(d2[e.to] > p&&d[e.to] < p)//这种p值介于最短与次短之间时要更新次短的距离。
{
d2[e.to] = p;
que.push((node){d2[e.to],e.to});//次短也可能对以后的结果有影响,所以也加入队列。
}
}
}
}
int main()
{
//freopen("in","r",stdin);
scanf("%d%d",&n,&m);
int from,to,dist;
for(int i = 0; i < m; ++i)
{
scanf("%d%d%d",&from,&to,&dist);
addedge(from,to,dist);
}
dijkstra(1);
cout<<d2
<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: