SPFA——路障Roadblock

来源:互联网 发布:知君本无邪 编辑:程序博客网 时间:2024/06/06 21:39

题目来源

洛谷P2176 [USACO14FEB]路障Roadblock

https://daniu.luogu.org/problem/show?pid=2176


思路

建图 求最短路长度len并记录路径 初始化答案为ans

枚举最短路路径中的边 把这条边的长度加倍 求此时的最短路长度

如果该长度与len的差大于ans 更新ans为该长度-len 还原该边长 继续枚举


代码(C++)

#include <cstdio>#include <queue>#include <bitset>using namespace std;bitset<110> in;queue<int> q;long long dis[1010]={0},length,ans=0;int n,m,u,v,w,cnt=0,pos,he[110],f[110];int en[10010],ne[10010],len[10010],fr[10010];inline void add();int main(){scanf("%d%d",&n,&m);for(int i=1;i<=m;++i)scanf("%d%d%d",&u,&v,&w),add();for(int j=1;j<n;++j)dis[j]=9223372036854775807;in[n]=1; q.push(n);while(!q.empty()){pos=q.front(); q.pop();  in[pos]=0;for(int k=he[pos];k!=0;k=ne[k])if(dis[pos]+len[k]<dis[en[k]]){dis[en[k]]=dis[pos]+len[k];f[en[k]]=k;if(in[en[k]]==0)q.push(en[k]),in[en[k]]=1;}}length=dis[1];for(int i=f[1];i!=0;i=f[fr[i]]){for(int j=1;j<n;++j)dis[j]=9223372036854775807;len[i]*=2;  in=0;  in[n]=1; q.push(n);while(!q.empty()){pos=q.front(); q.pop(); in[pos]=0;for(int k=he[pos];k!=0;k=ne[k])if(dis[pos]+len[k]<dis[en[k]]){dis[en[k]]=dis[pos]+len[k];if(in[en[k]]==0)q.push(en[k]),in[en[k]]=1;}}len[i]/=2;  in=0;if(dis[1]-length>ans)ans=dis[1]-length;}printf("%lld",ans);return 0;}inline void add(){en[++cnt]=v;len[cnt]=w;ne[cnt]=he[u];he[u]=cnt;  fr[cnt]=u;en[++cnt]=u;len[cnt]=w;ne[cnt]=he[v];he[v]=cnt;  fr[cnt]=v;}