您的位置:首页 > 其它

POJ 3463 Sightseeing

2016-08-16 17:59 302 查看

POJ 3463 Sightseeing

最短路变形,次短路

传送门:POJ

题意

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

思路

同时统计最短路和次短路,最后判断:如果次短路长度比最短路大1,那输出和;否则只输出最短路。

dijkstra基本框架不变,距离,方案数,vis数组都开二维,第二维是0或1,表示最短路/次短路。

松弛条件变化:

当前处理的距离小于对应最短路的距离,用最短路更新次短路,再用当前这个更新最短路;

当前处理的距离等于最短路的距离,更新方案数;

小于次短路距离,更新次短路;

等于次短路,更新次短路方案数。

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

代码

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: