poj3463 Sightseeing——次短路计数
Posted zinn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj3463 Sightseeing——次短路计数相关的知识,希望对你有一定的参考价值。
题目:http://poj.org/problem?id=3463
次短路计数问题,在更新最短路的同时分类成比最短路短、长于最短路而短于次短路、比次短路长三种情况讨论一下,更新次短路;
然而其实不必被“同时”限制,否则就容易像我一开始一样写挂...
像拆点一样把最短路和次短路完全分开,放进 dijkstra 的优先队列里,真是巧妙;
还要注意一点是直接更新最短路之后要把它的次短路也加进优先队列里,因为次短路同时也被更新了。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int const maxn=1005,maxm=10005; int T,n,m,head[maxn],ct,dis[maxn][3],f[maxn][3],s,t; bool vis[maxn][3]; struct N{ int to,next,w; N(int t=0,int n=0,int w=0):to(t),next(n),w(w) {} }edge[maxm]; struct P{ int bh,d,fl; P(int b=0,int d=0,int f=0):bh(b),d(d),fl(f) {} bool operator < (const P &y) const { return d>y.d;//priority_queue是从大到小排序 } }; priority_queue<P>q; void dijkstra() { while(q.size())q.pop(); memset(vis,0,sizeof vis); memset(f,0,sizeof f); memset(dis,0x3f,sizeof dis); dis[s][0]=0; f[s][0]=1; q.push(P(s,0,0)); while(q.size()) { int x=q.top().bh,d=q.top().d,fl=q.top().fl; q.pop(); if(vis[x][fl])continue; vis[x][fl]=1; for(int i=head[x];i;i=edge[i].next) { int u=edge[i].to,w=edge[i].w; if(dis[u][0]>d+w) { dis[u][1]=dis[u][0]; f[u][1]=f[u][0]; dis[u][0]=d+w; f[u][0]=f[x][fl]; q.push(P(u,dis[u][0],0)); q.push(P(u,dis[u][1],1));//! } else if(dis[u][0]==d+w) f[u][0]+=f[x][fl]; else if(dis[u][1]>d+w) { dis[u][1]=d+w; f[u][1]=f[x][fl]; q.push(P(u,dis[u][1],1)); } else if(dis[u][1]==d+w) f[u][1]+=f[x][fl]; } } } int main() { scanf("%d",&T); while(T--) { memset(head,0,sizeof head); ct=0; scanf("%d%d",&n,&m); for(int i=1,x,y,z;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); edge[++ct]=N(y,head[x],z); head[x]=ct; } scanf("%d%d",&s,&t); dijkstra(); if(dis[t][1]==dis[t][0]+1)f[t][0]+=f[t][1]; printf("%d ",f[t][0]); } return 0; }
以上是关于poj3463 Sightseeing——次短路计数的主要内容,如果未能解决你的问题,请参考以下文章