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;
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;
}
转载请注明原文地址: https://ju.6miu.com/read-1311607.html