注意这里求的不是两点间的第二短长度...就是说如果两点间距离有两条路径都是最短路径~~那最第二短路径长度还是这个最短路径..
做了POJ2449的两点间K短路后这道题就是它的缩小版...唯一要留意的就是边是无向边....
Program:
#include<iostream>
#include<queue>
#define MAXN 200001
using namespace std;
struct node
{
int h,g,p;
bool operator < (node a) const
{
return a.h+a.g<h+g;
}
};
struct nodeOfLine
{
int x,y,w,next;
}line[MAXN];
int n,r,link[5001],g[5001];
priority_queue<node> myqueue;
void djikstra()
{
int i,j,k,t;
bool used[MAXN];
memset(g,0x7F,sizeof(g));
memset(used,false,sizeof(used));
g[n]=0;
for (t=1;t<=n;t++)
{
j=0;
for (i=1;i<=n;i++)
if (!used[i] && (!j || g[i]<g[j])) j=i;
used[j]=true;
k=link[j];
while (k)
{
if (g[line[k].y]>g[line[k].x]+line[k].w)
g[line[k].y]=g[line[k].x]+line[k].w;
k=line[k].next;
}
}
return;
}
int Astar()
{
node h,temp;
int times[5001],k;
while (!myqueue.empty()) myqueue.pop();
memset(times,0,sizeof(times));
h.p=1; h.h=h.g=0;
myqueue.push(h);
while (!myqueue.empty())
{
h=myqueue.top();
myqueue.pop();
times[h.p]++;
if (times[h.p]>2) continue;
if (times[h.p]==2 && h.p==n) return h.h+h.g;
k=link[h.p];
while (k)
{
temp.p=line[k].y;
temp.h=h.h+line[k].w;
temp.g=g[line[k].y];
myqueue.push(temp);
k=line[k].next;
}
}
return -1;
}
int main()
{
scanf("%d%d",&n,&r);
memset(link,0,sizeof(link));
for (int i=1;i<=r;i++)
{
scanf("%d%d%d",&line[i*2-1].x,&line[i*2-1].y,&line[i*2-1].w);
line[i*2-1].next=link[line[i*2-1].x]; link[line[i*2-1].x]=i*2-1;
line[i*2].x=line[i*2-1].y; line[i*2].y=line[i*2-1].x; line[i*2].w=line[i*2-1].w;
line[i*2].next=link[line[i*2].x]; link[line[i*2].x]=i*2;
}
r*=2;
djikstra();
printf("%d\n",Astar());
return 0;
}