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;
}

posted @ 2010-06-09 18:50  北海小龙  阅读(497)  评论(0编辑  收藏  举报