我是靠谱客的博主 年轻乌龟,最近开发中收集的这篇文章主要介绍luogu1608 路径统计 (spfa),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题意:给一个有向图(无零边),要求找出最短路的数量(重边只计算一次)
做spfa的时候,记一个cnt
对于u-w->v如果dis[u]+w=dis[v],cnt[v]+=cnt[u]
如果dis[u]+w<dis[v],cnt[v]=cnt[u]
要注意的是,不论是大于还是等于,都需要把v加到队列里继续去更新
(如果等于时不加,那么有可能v这个点在增加u->v之前更新过后面的点,这个后面的点就不会加从u来的路径)
那既然等于时也要加入队列,那么有可能一个点就会给后面的更新两次,那么在更新过一次后直接把cnt[u]给成0即可
然而不能让N这个点被给成0,其实N这个点根本就没必要被加入队列,发现有N的时候跳过即可
最后答案就是cnt[N]

 

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=2020;
int rd(){
int x=0;char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
struct Edge{
int a,b,l,ne;
}eg[maxn*maxn];
int N,M,egh[maxn],ect;
int eg2[maxn][maxn];
int ans[maxn];
int dis[maxn];bool flag[maxn];
queue<int> q;
void adeg(int a,int b,int l){
eg[ect].a=a;eg[ect].b=b;eg[ect].l=l;eg[ect].ne=egh[a];
eg2[a][b]=l;egh[a]=ect++;
}
void spfa(){
memset(dis,127,sizeof(dis));
dis[1]=0;ans[1]=1;q.push(1);
while(!q.empty()){
int p=q.front();q.pop();flag[p]=0;
if(p==N) continue;
for(int i=egh[p];i!=-1;i=eg[i].ne){
int j=eg[i].b;
if(dis[j]==dis[p]+eg[i].l){
ans[j]+=ans[p];
if(!flag[j]) q.push(j);flag[j]=1;
}
if(dis[j]>dis[p]+eg[i].l){
dis[j]=dis[p]+eg[i].l;
ans[j]=ans[p];
if(!flag[j]) q.push(j);flag[j]=1;
}
}ans[p]=0;
}
}
int main(){
int i,j,k;
N=rd();M=rd();
memset(egh,-1,sizeof(egh));memset(eg2,127,sizeof(eg2));
for(i=1;i<=M;i++){
int a=rd(),b=rd(),c=rd();
if(eg2[a][b]>c) adeg(a,b,c);
}
spfa();
if(dis[N]>10*N) printf("No answern");
else printf("%d %dn",dis[N],ans[N]);
}

 

转载于:https://www.cnblogs.com/Ressed/p/9354320.html

最后

以上就是年轻乌龟为你收集整理的luogu1608 路径统计 (spfa)的全部内容,希望文章能够帮你解决luogu1608 路径统计 (spfa)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部