POJ 3255
//题目类型;最短路--求次短路的长度
//基本方法从起点s出发求一次最短路,用 d[] 记录最短路径长度,从终点 t 对反向图求一次最短路径,rd[]记录最短距离,
//然后枚举每一条边 <u,v>,取 d[u]+ w(u,v)+ rd[v] 最小而又大于最短路径的就是次短路径。
#include <iostream>
#include <queue>
//#include <conio.h>
using namespace std;
#define rarray 100001
#define narray 5001
typedef struct edge
{
int u;
int v;
int w;
edge *next;
}edge;
edge *adj[narray],edges[rarray*2];
typedef struct node
{
int v;
int w;
bool operator<(const node&a)const
{
return w>a.w;
}
}node;
const int INF = 0x7fffffff;
int n,r;
int edgenum;
void addEdge(int start,int end,int weight)
{
edge* ptr = &edges[edgenum++];
ptr->u = start;
ptr->v = end;
ptr->w = weight;
ptr->next = adj[start];
adj[start] = ptr;
}
void Dij(int src,int d[])
{
int i,j;
node tempnode;
priority_queue<node> myqueue;
for(i=1;i<=n;++i) d[i] = INF;
d[src] = 0;
tempnode.v = src;
tempnode.w = 0;
myqueue.push(tempnode);
while(!myqueue.empty())
{
int frontv = myqueue.top().v;
int frontw = myqueue.top().w;
myqueue.pop();
if(d[frontv]!=frontw) continue;
for(edge *ptr = adj[frontv];ptr;ptr=ptr->next)
{
int tempv = ptr->v;
int tempw = ptr->w;
if(d[tempv]>d[frontv]+tempw)
{
d[tempv] = d[frontv]+tempw;
tempnode.v = tempv;
tempnode.w = d[tempv];
myqueue.push(tempnode);
}
}
}
}
int main()
{
//freopen("1.txt","r",stdin);
int i,j;
int start,end,weight;
int src,des;
int d[narray],rd[narray];
while(scanf("%d%d",&n,&r)!=-1)
{
edgenum = 0;
src = 1;
des = n;
for(i=1;i<=n;++i)
{
adj[i] = NULL;
}
for(i=1;i<=r;++i)
{
scanf("%d%d%d",&start,&end,&weight);
addEdge(start,end,weight);
addEdge(end,start,weight);
}
Dij(src,d);
Dij(des,rd);
int min = INF;
for(i=0;i<edgenum;++i)
{
int tempu = edges[i].u;
int tempv = edges[i].v;
int tempw = edges[i].w;
int dis = d[tempu]+tempw+rd[tempv];
if(dis>d[des] && dis<min)
{
min = dis;
}
}
printf("%d\n",min);
}
//getch();
return 0;
}