首页 > 代码库 > poj 3463 Sightseeing 最短路径数量
poj 3463 Sightseeing 最短路径数量
题意:
求有向图中最短路和比最短路大1的路径数量。
思路:
需要理解dijkstra算法中dis[n]数组的含义,设cnt[i]表示到点i的最短路径数量,cnt1[i]表示到点i比最短路大1的路径数量。在运行dijkstra算法的过程中每次获得最小dis[i]的时候可以对所有dis[v]+w(v,i)==dis[i]的v做如下更新cnt[i]+=cnt[v],cnt1[i]+=cnt1[v]。而当所有值为某数的dis[i]计算完成时也就是对任意i,dis[i]为同一值且不再变化时,可以对这些满足dis[i]+1=dis[v]+w(v,i)的点i做如下更新:cnt1[i]+=cnt[v];最后结果为cnt[f]+cnt1[f]。
//poj 3463 //sepNINE #include <iostream> #include <queue> using namespace std; const int maxN=1024; const int maxM=10024; int head[maxN]; int head1[maxN]; int dis[maxN]; int cnt[maxN]; int cnt1[maxN]; int n,m,e,e1,s,f; typedef pair<int,int> pii; priority_queue<pii,vector<pii>,greater<pii> > q; struct Edge { int v,w,next; }edge[maxM],edge1[maxM]; void update(int maxDis) { int i; for(int i=1;i<=n;++i){ if(dis[i]==maxDis){ for(int e=head1[i];e!=-1;e=edge1[e].next){ int v=edge1[e].v,w=edge1[e].w; if(dis[v]+w==dis[i]+1) cnt1[i]+=cnt[v]; } } } } int dij(int s,int t) { memset(cnt,0,sizeof(cnt)); memset(cnt1,0,sizeof(cnt1)); int i,maxDis; for(i=1;i<=n;++i) dis[i]=INT_MAX; dis[s]=0; cnt[s]=1; maxDis=0; q.push(make_pair(dis[s],s)); while(!q.empty()) { pii u=q.top();q.pop(); int x=u.second; if(u.first>dis[x]) continue; if(maxDis<dis[x]){ update(maxDis); maxDis=dis[x]; } for(int e=head1[x];e!=-1;e=edge1[e].next){ int v=edge1[e].v,w=edge[e].w; if(dis[v]+w==dis[x]){ cnt[x]+=cnt[v]; cnt1[x]+=cnt1[v]; } } for(int e=head[x];e!=-1;e=edge[e].next) if(dis[x]+edge[e].w<dis[edge[e].v]){ dis[edge[e].v]=dis[x]+edge[e].w; q.push(make_pair(dis[edge[e].v],edge[e].v)); } } update(maxDis); return dis[t]; } int main() { int cases; scanf("%d", &cases); while(cases--){ memset(head,-1,sizeof(head)); memset(head1,-1,sizeof(head1)); e=e1=0; scanf("%d%d",&n,&m); while(m--){ int a,b,c; scanf("%d%d%d",&a,&b,&c); edge[e].v=b;edge[e].w=c;edge[e].next=head[a];head[a]=e++; edge1[e1].v=a;edge1[e1].w=c;edge1[e1].next=head1[b];head1[b]=e1++; } scanf("%d%d",&s,&f); dij(s,f); printf("%d\n",cnt[f]+cnt1[f]); } return 0; }
代码:
poj 3463 Sightseeing 最短路径数量
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。