POJ 3463 Sightseeing

来源:互联网 发布:java se技术文档 编辑:程序博客网 时间:2024/04/29 01:34

POJ 3463 Sightseeing

最短路变形,次短路

传送门:POJ


题意

已知一张图(单向边),起点S和终点F,求从S到F的最短路和比最短路长1的路径的条数之和。


思路

同时统计最短路和次短路,最后判断:如果次短路长度比最短路大1,那输出和;否则只输出最短路。
dijkstra基本框架不变,距离,方案数,vis数组都开二维,第二维是0或1,表示最短路/次短路。
松弛条件变化:

  1. 当前处理的距离小于对应最短路的距离,用最短路更新次短路,再用当前这个更新最短路;
  2. 当前处理的距离等于最短路的距离,更新方案数;
  3. 小于次短路距离,更新次短路;
  4. 等于次短路,更新次短路方案数。

每次松弛后把新的点加入队列。


代码

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;const int MAXN=20007;const int oo=1000000007;typedef long long LL;struct Graph{    int next;    int to;    int cost;}G[MAXN];int head[MAXN];struct Queue{    int point;    int dis;    int kind;//0表示最短路1表示次短路    Queue(){}    Queue(int _point,int _dis,int _kind){ point=_point;dis=_dis; kind=_kind; }    bool operator <(const Queue &a) const    {        return dis>a.dis;    }};int d[MAXN][2];int d_n[MAXN][2];int dijkstra(int n,int m,int s,int t)//点数,边数,起点,终点{    memset(d,0x3f,sizeof(d));    memset(d_n,0,sizeof(d_n));    priority_queue<Queue> que;    d_n[s][0]=1;d[s][0]=0;    while(!que.empty()) que.pop();    que.push(Queue(s,0,0));    while(!que.empty())    {        Queue temp=que.top();        que.pop();        if(temp.dis>d[temp.point][temp.kind]) continue;        int pn=temp.point;        for(int i=head[pn];i!=-1;i=G[i].next)        {            int dis1,to1;            dis1=temp.dis+G[i].cost;            to1=G[i].to;            if(dis1<d[to1][0])            {                if(d[to1][0]<d[to1][1])                {                    d[to1][1]=d[to1][0];d_n[to1][1]=d_n[to1][0];                    que.push(Queue(to1,d[to1][1],1));                }                d[to1][0]=dis1;d_n[to1][0]=d_n[pn][0];                que.push(Queue(to1,dis1,0));            }            else if(dis1==d[to1][0])            {                d_n[to1][0]+=d_n[pn][0];            }            else if(dis1<d[to1][1])            {                d[to1][1]=dis1;                d_n[to1][1]=d_n[pn][temp.kind];                que.push(Queue(to1,dis1,1));            }            else if(dis1==d[to1][1])            {                d_n[to1][1]+=d_n[pn][temp.kind];            }        }    }    if(d[t][0]+1==d[t][1]) return d_n[t][0]+d_n[t][1];    else return d_n[t][0];}int main(){    int T;    scanf("%d",&T);    while(T--)    {        int n,m;        scanf("%d%d",&n,&m);        memset(head,-1,sizeof(head));        memset(G,0,sizeof(G));        for(int i=0;i<m;i++)        {            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            G[i].to=b;G[i].cost=c;G[i].next=head[a];head[a]=i;        }        int s,t;        scanf("%d%d",&s,&t);        int res=dijkstra(n,m,s,t);        printf("%d\n",res);    }    return 0;}
0 0
原创粉丝点击