不是费用流都需要用 SPFA 吗。

众所周知,SPFA 去世了,然后网络流显然有负边。于是我们可以像 Johnson 全源最短路一样,给边加上势能,具体实现看我之前的 博客 啦。

然后对于每一次跑 Dijkstra ,然后得到最短路,把势能要再加上这个最短路,可以证明这样操作一次图上不会再有负边。

也正因如此我们不能用 \(dinic\) ,我们不保证在走了多条增广路后仍然边权非负,所以我们可以记录最短路的路径,然后每次增广一条,这样就能保证正确。这个似乎是 KM算法吗?反正都是增广一条,没有学过KM,所以不敢下定论。

code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define file(a) freopen(#a".in","r",stdin),freopen(#a".out","w",stdout)
inline int read(){
int s=0,f=1;char ch=getchar();
while(ch<'0'||'9'<ch) {if(ch=='-') f=-1;ch=getchar();}
while('0'<=ch&&ch<='9') {s=s*10+(ch^48);ch=getchar();}
return s*f;
}
const int N=5e3+3;
const int INF=0x3f3f3f3f;
int n,m,S,T;
struct Edge{
int v,w,c;
};
vector<int>head,nxt;
vector<Edge>to;
inline void join(int u,int v,int w,int c){
nxt.push_back(head[u]);
head[u]=to.size();
to.push_back({v,w,c});
}
queue<int>Q;
int h[N];
bool inq[N];
inline void spfa(){
for(int i=1;i<=n;++i) h[i]=INF,inq[i]=0;
h[S]=0;Q.push(S);inq[S]=1;h[S]=0;
while(!Q.empty() ){
int u=Q.front();Q.pop();inq[u]=0;
for(int i=head[u];~i;i=nxt[i]){
int v=to[i].v,c=to[i].c,w=to[i].w;
if(w and h[v]>h[u]+c){
h[v]=h[u]+c;
if(!inq[v]){
inq[v]=1;
Q.push(v);
}
}
}
}
}
int dis[N];
struct node{
int d,x;
inline friend bool operator <(node x,node y){
return x.d<y.d;
}
};
int cur[N];bool vis[N];
struct way{
int v,id;
}e[N];
priority_queue<node>q;
inline bool dijkstra(){
while(!q.empty() ) q.pop();
for(int i=1;i<=n;++i) dis[i]=INF,vis[i]=0;
dis[S]=0;q.push({0,S});
while(!q.empty() ){
int u=q.top().x;q.pop();
if(vis[u]) continue;vis[u]=1;
for(int i=head[u];~i;i=nxt[i]){
int v=to[i].v,w=to[i].w,c=to[i].c+h[u]-h[v];
if(w and dis[v]>dis[u]+c){
e[v].v=u;
e[v].id=i;
dis[v]=dis[u]+c;
if(!vis[v]){
q.push({-dis[v],v});
}
}
}
}
return dis[T]!=INF;
}
int minc,maxf;
inline void PD(){
while(dijkstra() ){
for(int i=S;i<=T;++i) h[i]+=dis[i];
ll minf=INF;
for(int i=T;i!=S;i=e[i].v){
minf=min(minf,to[e[i].id].w);
}
for(int i=T;i!=S;i=e[i].v){
to[e[i].id].w-=minf;
to[e[i].id^1].w+=minf;
minc+=minf*to[e[i].id].c;
}
maxf+=minf;
}
}
int main(){
//file(a);
//freopen("a.in","r",stdin);
n=read();m=read();S=read();T=read();
head.resize(n+1,-1);
for(int i=1;i<=m;++i){
int u=read(),v=read(),w=read(),c=read();
join(u,v,w,c);join(v,u,0,-c);
}
spfa();
PD();
printf("%d %d\n",maxf,minc);
return 0;
}

Primal_Dual 原始对偶的更多相关文章

  1. 费用流 Dijkstra 原始对偶方法(primal-dual method)

    简单叙述用Dijkstra求费用流 Dijkstra不能求有负权边的最短路. 类似于Johnson算法,我们也可以设计一个势函数,以满足在与原图等价的新图中的边权非负. 但是这个算法并不能处理有负圈的 ...

  2. Superpixel Based RGB-D Image Segmentation Using Markov Random Field——阅读笔记

    1.基本信息 题目:使用马尔科夫场实现基于超像素的RGB-D图像分割: 作者所属:Ferdowsi University of Mashhad(Iron) 发表:2015 International ...

  3. [转]从入门到精通: 最小费用流的“zkw算法”

    >>>> 原文地址:最小费用流的“zkw算法” <<<< 1. 网络流的一些基本概念 很多同学建立过网络流模型做题目, 也学过了各种算法, 但是对于基本 ...

  4. 详解zkw算法解决最小费用流问题

    网络流的一些基本概念 很多同学建立过网络流模型做题目, 也学过了各种算法, 但是对于基本的概念反而说不清楚. 虽然不同的模型在具体叫法上可能不相同, 但是不同叫法对应的思想是一致的. 下面的讨论力求规 ...

  5. 网络流板子/费用流板子 2018南京I题+2016青岛G题

    2018南京I题: dinic,链式前向星,数组队列,当前弧优化,不memset全部数组,抛弃满流点,bfs只找一条增广路,每次多路增广 #include <bits/stdc++.h> ...

  6. Luogu P3381 (模板题) 最小费用最大流

    <题目链接> 题目大意: 给定一张图,给定条边的容量和单位流量费用,并且给定源点和汇点.问你从源点到汇点的最带流和在流量最大的情况下的最小费用. 解题分析: 最小费用最大流果题. 下面的是 ...

  7. 省队集训 Day3 吴清华

    [题目大意] 给网格图,共有$n * n$个关键节点,横向.纵向距离均为$d$,那么网格总长度和宽度均为$(n+1) * d + 1$,最外围一圈除了四角是终止节点.要求每个关键节点都要通过线连向终止 ...

  8. 【P2405】方格取数问题加强版(费用流)

    考虑如何建图.还是老样子先拆点,然后把每两个点之间连接两条边,一条流量为1,费用为-点权,处理是否走这个点.一条流量无限,没有费用,因为哪怕一个点选过了,它的地方还是可以重复走过去的. 然后把经由一个 ...

  9. Andrew Ng机器学习笔记+Weka相关算法实现(五)SVM最优间隔和核方法

    这一章主要解说Ng的机器学习中SVM的兴许内容.主要包括最优间隔分类器求解.核方法. 最优间隔分类器的求解 利用以一篇讲过的的原始对偶问题求解的思路,我们能够将相似思路运用到SVM的求解上来. 详细的 ...

随机推荐

  1. 设计模式-观察者模式Observe的实现

    using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> / ...

  2. python-成绩转换

    本题要求编写程序将一个百分制成绩转换为五分制成绩.转换规则: 大于等于90分为A: 小于90且大于等于80为B: 小于80且大于等于70为C: 小于70且大于等于60为D: 小于60为E. 输入样例: ...

  3. 人机交互BS

    B/S结构用户界面设计       [实验编号] 10003809548j Web界面设计 [实验学时] 8学时 [实验环境] l  所需硬件环境为微机: l  所需软件环境为dreamweaver ...

  4. git-flow-avh的使用过程

    安装: 在mac上 brew install git-flow-avh 使用: 在仓库中 git flow init 一路回车就行,这个命令相当于写入一些默认命令流程到.git中, 此命令执行之后会增 ...

  5. EMS修改邮箱容量限制的方法

    使用PowerShell命令完成邮箱数据库限制任务. 以Exchange管理员身份打开EMS控制台.在PowerShell命令提示符下,键入如下命令. Set-MailboxDatabase Test ...

  6. spring-aop相关概念

    如果下面有疑问请看完动态代理技术的分析 Aop术语: Target(目标对象):要被增强的方法的对象 Proxy(代理对象):简单的说就是对目标对象进行增强的代理类 Joinpoint(连接点):可以 ...

  7. 解决k8s故障,eureka处于unknow的问题

    //pod Unknown状态,开始强制删除eureka-server-node-0,eureka-server-node-1等,强制删除不了 [root@fp158 sts]# kubectl de ...

  8. 另类终端「GitHub 热点速览 v.22.15」

    作者:HelloGitHub-小鱼干 除了编译器之外,终端也是我们日常打交道的软件之一.但,你用它看过股票吗?OpenBBTerminal 不仅能让你看股票,还能让你用科学的方法进行股票投资.说到投资 ...

  9. Casdoor + OAuth 实现单点登录 SSO

    简介 Casdoor 是一个基于 OAuth 2.0 / OIDC 的中心化的单点登录(SSO)身份验证平台,简单来说,就是 Casdoor 可以帮你解决用户管理的难题,你无需开发用户登录.注册等与用 ...

  10. golang内存对齐分析(转载)

    问题 type Part1 struct { a bool b int32 c int8 d int64 e byte } 在开始之前,希望你计算一下 Part1 共占用的大小是多少呢? func m ...