dij费用流/Johnson Reweighting
dij费用流/Johnson Reweighting
我们一般敲的费用流都是套\(SPFA\)的\(dinic\),这是因为会有负边权,\(dij\)做不了,考虑能不能动点手脚使得我们的边权变成正的
可能会直接想到给每条边+\(INF\),这显然有点难蚌
\(Johnson\ Reweighting\)就是用来解决这个问题的
考虑给每个点赋一个点权\(h[x]\),表示\(S\)走到\(x\)的最短路的长度,我们现在让边\((u,v,w)\)的权变成\(w+h[u]-h[v]\),因为\(h\)是最短距离,所以显然这个值\(\geq 0\),且这样直接跑\(dij\)得到的\(S\)到\(T\)的最短路距离\(v\)加上\(-dis[S]+dis[T]\)就是真正的最短路距离
那么考虑怎么快速得到这个\(h\),显然第一次就直接跑个\(SPFA\),考虑后面怎么办
对于第\(i\)(\(i>1\))次跑\(dij\)时,记\(h_i\)表示跑完第\(i\)次\(dij\)后的最短路
显然我们想用\(h_i\)来操作第\(i\)次\(dij\),但显然这不现实
发现就用\(h_{i-1}\)来操作的话,所有边权也都是非负的,因为对于第\(i-1\)次\(dij\),它会改变的边\((u,v,w)\)满足\(w+h[u]-h[v]=0\)
复杂度是\(O(F(M+NlogN))\),好像\(OI\)里一般常写成\(O(F(N+M)logN)\)
模板(https://www.luogu.com.cn/problem/P3381):
#include<bits/stdc++.h>
using namespace std;
const int N=5e3+5,M=5e4+5,INF=1e9;
int n,m,S,T;
int head[N],cnt=1;
struct node{ int nxt,v,val,w; }tree[M<<1];
void add(int u,int v,int val,int w){
tree[++cnt]={head[u],v,val,w},head[u]=cnt;
tree[++cnt]={head[v],u,0,-w},head[v]=cnt;
}
int dis[N]; bool vis[N];
void spfa(){
for(int i=1;i<=n;++i) dis[i]=INF;
dis[S]=0; queue<int> q; q.push(S);
while(!q.empty()){
int x=q.front(); q.pop(),vis[x]=false;
for(int i=head[x],y;i;i=tree[i].nxt) if(tree[i].val&&dis[y=tree[i].v]>dis[x]+tree[i].w){
dis[y]=dis[x]+tree[i].w;
if(!vis[y]) q.push(y),vis[y]=true;
}
}
}
struct use{
int x,d;
bool operator < (const use &other)const{
return d>other.d;
}
};
int h[N],fr[N],ans,ans1;
bool dij(){
priority_queue<use> q;
for(int i=1;i<=n;++i) dis[i]=INF,vis[i]=false;
q.push({S,dis[S]=0});
while(!q.empty()){
int x=q.top().x; q.pop();
if(vis[x]) continue;
vis[x]=true;
for(int i=head[x],y;i;i=tree[i].nxt) if(tree[i].val&&!vis[y=tree[i].v]){
int t=dis[x]+tree[i].w+h[x]-h[y];
if(t<dis[y]) dis[y]=t,fr[y]=i,q.push({y,dis[y]});
}
}
if(dis[T]==INF) return false;
int mn=INF;
for(int x=T,i=fr[x];x!=S;x=tree[i^1].v,i=fr[x]) mn=min(mn,tree[i].val);
ans+=mn;
for(int x=T,i=fr[x];x!=S;x=tree[i^1].v,i=fr[x]) tree[i].val-=mn,tree[i^1].val+=mn,ans1+=mn*tree[i].w;
for(int i=1;i<=n;++i) if(dis[i]<INF) h[i]+=dis[i];
return true;
}
int main(){
scanf("%d%d%d%d",&n,&m,&S,&T);
for(int i=1,u,v,val,w;i<=m;++i) scanf("%d%d%d%d",&u,&v,&val,&w),add(u,v,val,w);
spfa(); for(int i=1;i<=n;++i) h[i]=dis[i];
while(dij());
printf("%d %d\n",ans,ans1);
return 0;
}
dij费用流/Johnson Reweighting的更多相关文章
- dij 费用流
#include <bits/stdc++.h> using namespace std; typedef long long lld; const int MAXN = 50010, M ...
- HDU 4780 Candy Factory(拆点费用流)
Problem Description A new candy factory opens in pku-town. The factory import M machines to produc ...
- 洛谷P3381 【模板】最小费用最大流(dijstra费用流)
题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表 ...
- 费用流 Dijkstra 原始对偶方法(primal-dual method)
简单叙述用Dijkstra求费用流 Dijkstra不能求有负权边的最短路. 类似于Johnson算法,我们也可以设计一个势函数,以满足在与原图等价的新图中的边权非负. 但是这个算法并不能处理有负圈的 ...
- 网络流小记(EK&dinic&当前弧优化&费用流)
欢 迎 来 到 网 络 瘤 的 世 界 什么是网络流? 现在我们有一座水库,周围有n个村庄,每个村庄都需要水,所以会修水管(每个水管都有一定的容量,流过的水量不能超过容量).最终水一定会流向唯一一个废 ...
- 补 第三场多校杭电 费用流 K Subsequence
K Subsequence 这个题目是这个人想吃东西,但是他每次吃的都是他的美味值都必须不递减,可以吃k次,问这个最大的美味值是多少. 这个是一个比较明显的费用流,建图也很好建,但是呢,这个题目卡sp ...
- hdu-5988 Coding Contest(费用流)
题目链接: Coding Contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Ot ...
- POJ2195 Going Home[费用流|二分图最大权匹配]
Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22088 Accepted: 11155 Desc ...
- BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]
3130: [Sdoi2013]费用流 Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 960 Solved: 5 ...
- 洛谷 1004 dp或最大费用流
思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...
随机推荐
- 【python日期和时间处理】time模块基本使用
1. time模块中三种时间格式 时间戳 time模块获取各种精度的时间戳 import time timestamp = time.time() timestamp_s = int(time.tim ...
- datasnap的restful服务器
说真话,这玩意真的简单好用.但你要控制好: 1.内存泄漏和异常处理好: 2.有没有发现,通过服务器对数据库进行读写时,在资源管理器中,如果是sql server,就会看到连接1433的连接一直挂在那里 ...
- .net WorkFlow 流程会签
WikeFlow官网:www.wikesoft.com WikeFlow学习版演示地址:workflow.wikesoft.com WikeFlow学习版源代码下载:https://gitee.com ...
- symfony或doctrine报错:Object of class App\Entity\* could not be converted to string
报错: Catchable Fatal Error: Object of class App\Entity\ProjectType could not be converted to string 版 ...
- 【记录】ChatGPT|使用技巧(更新至2023年2月8日)
昨天,2022年12月13日,在下午和晚上,ChatGPT 就开始因为请求过多而写到一半就崩溃,出现network error,可见它的关注度确实是越来越可观了. 正好最近世界杯,有博客活动, ...
- 基于主成分分析(PCA)的数据降维
一.概述 主成分分析(Principal Component Analysis,PCA)是一种用于数据降维的方法,其核心目标是在尽可能保留原始数据信息的前提下,将高维数据映射到低维空间.该算法基于 ...
- 用JavaScript打造全新编程语言:从无到有的完整实践指南
@charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...
- B1037 在霍格沃茨找零钱
如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 -- 就如海格告诉哈利的:"十七个银西可(Sickle)兑一个加隆(Galleon),二十九个纳特(Knut)兑一个西可,很容易.& ...
- ES查询优化随记1: 多路向量查询 & KNN IO排查 & 高效Filter使用
哈哈最近感觉自己不像算法倒像是DB,整天围着ES打转,今天查IO,明天查内存,一会优化查询,一会优化吞吐.毕竟RAG离不开知识库,我们的选型是ES,于是这一年都是和ES的各种纠葛.所以顺手把近期获得的 ...
- Disruptor—4.与Netty的简单应用
大纲 1.服务端代码最佳实践 2.客户端代码最佳实践 3.Netty的高性能核心问题分析 4.基于Disruptor异步化处理Netty的长链接业务 5.Disruptor核心池化封装实现 6.实现接 ...