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; }
相关文章推荐
- poj3463 Sightseeing(读题很重要)
- POJ 3463 Sightseeing 次短路
- POJ 3463 Sightseeing【次短路,Dijkstra算法,链式前向星建图】
- poj 3463 Sightseeing(最短路次短路)
- POJ 3463 Sightseeing dijkstra
- POJ 3463 Sightseeing
- poj 3463 Sightseeing
- POJ 3463 Sightseeing
- POJ 3463 Sightseeing
- POJ 3463 Sightseeing 最短路+次短路
- poj 3463 Sightseeing 将spfa进行到底!!!
- POJ-3463: Sightseeing 【最短路次短路及条数】
- POJ 3463 Sightseeing(最短路次短路计数)
- POJ 3463 Sightseeing (次短路,Dijkstra拓展)
- POJ 3463:Sightseeing
- poj 3463 Sightseeing
- poj 3463 Sightseeing(dij求最短路+次短路(比最短路长1)的总走法)
- POJ 3463 Sightseeing(次短路)
- poj 3463 Sightseeing
- POJ 3463 Sightseeing 次短路条数