网络流相关技术

news/2024/12/23 11:37:35/文章来源:https://www.cnblogs.com/EmilyDavid/p/18623612

基础部分

最大流

Dinic

板子
#include<bits/stdc++.h>using namespace std;
typedef long long ll;#define gc getchar
ll rd(){ll f=1,r=0;char ch=gc();while(!isdigit(ch)){ if(ch=='-') f=-1;ch=gc();}while(isdigit(ch)){ r=(r<<3)+(r<<1)+(ch^48);ch=gc();}return f*r;
}const int maxn=210,maxm=5010,inf=0x3f3f3f3f;
int n,m,s,t,tot=1,head[maxn],cur[maxn],dep[maxn];
ll ans;
struct edge{int v,nxt;ll f;
}e[maxm<<1];void add(int u,int v,int w){e[++tot].v=v;e[tot].f=w;e[tot].nxt=head[u];head[u]=tot;
}bool bfs(){for(int i=1;i<=n;++i) dep[i]=0,cur[i]=head[i];queue<int> q;q.push(s);dep[s]=1;while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i;i=e[i].nxt){int v=e[i].v;ll f=e[i].f;if(f&&!dep[v]){dep[v]=dep[u]+1;q.push(v);}}}return dep[t];
}ll dfs(int u,ll fl){if(u==t||!fl) return fl;ll used=0;for(int i=cur[u];i&&fl;i=e[i].nxt){cur[u]=i;int v=e[i].v;ll f=min(e[i].f,fl);if(dep[v]==dep[u]+1&&f){ll k=dfs(v,f);e[i].f-=k,e[i^1].f+=k;fl-=k,used+=k;}}if(!used) dep[u]=-1;return used;
}void dinic(){while(bfs()) ans+=dfs(s,1e18);
}int main(){n=rd(),m=rd(),s=rd(),t=rd();for(int i=1;i<=m;++i){int u=rd(),v=rd(),w=rd();add(u,v,w);add(v,u,0);}dinic();printf("%lld\n",ans);return 0;
}

时间复杂度为\(O(n^2m)\),但大多数情况跑不满,不会被卡。但要是\(n=10^6\)了还是想想其他办法吧。

HLPP

板子
#include<bits/stdc++.h>using namespace std;const int maxn=1210,maxm=120010;
int s,t,n,m,tot=1,maxh,head[maxn],h[maxn],gap[maxn];
long long ex[maxn];
stack<int> b[maxn];
struct edge{int v,nxt;long long w;
}e[maxm<<1];void add(int u,int v,long long w){e[++tot].v=v;e[tot].w=w;e[tot].nxt=head[u];head[u]=tot;
}int getmxh(){while(b[maxh].empty()&&maxh>-1) maxh--;return maxh==-1?0:b[maxh].top();
}bool bfs(){memset(h,0x3f3f3f3f,sizeof(h));h[t]=0;queue<int> q;q.push(t);while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i;i=e[i].nxt){int v=e[i].v;if(e[i^1].w&&h[v]>h[u]+1){h[v]=h[u]+1;q.push(v);}}}return h[s]!=0x3f3f3f3f;
}bool push(int u){bool p=(u==s);for(int i=head[u];i;i=e[i].nxt){int v=e[i].v,w=p?e[i].w:min(ex[u],e[i].w);if(!w||(!p&&h[u]!=h[v]+1)||h[v]==0x3f3f3f3f) continue;if(v!=s&&v!=t&&!ex[v]) b[h[v]].push(v),maxh=max(maxh,h[v]);ex[u]-=w,ex[v]+=w;e[i].w-=w,e[i^1].w+=w;if(!ex[u]) return 0; }return 1;
}void relabel(int u){h[u]=0x3f3f3f3f;for(int i=head[u];i;i=e[i].nxt){int v=e[i].v,w=e[i].w;if(!w) continue;h[u]=min(h[u],h[v]+1);}if(h[u]<n){b[h[u]].push(u);gap[h[u]]++;maxh=max(maxh,h[u]);}
}long long hlpp(){if(!bfs()) return 0;memset(gap,0,sizeof(gap));for(int i=1;i<=n;++i){if(h[i]!=0x3f3f3f3f) gap[h[i]]++;}h[s]=n,push(s);int u;while((u=getmxh())){b[maxh].pop();if(push(u)){if(!--gap[h[u]]){for(int i=1;i<=n;++i){if(i!=s&&i!=t&&h[i]>h[u]&&h[i]<n+1) h[i]=n+1;}}relabel(u);}}return ex[t];
}int main(){scanf("%d%d%d%d",&n,&m,&s,&t);for(int i=1;i<=m;++i){int u,v;long long w;scanf("%d%d%lld",&u,&v,&w);add(u,v,w);add(v,u,0);}printf("%lld\n",hlpp());return 0;
} 

时间复杂度\(O(n^2\sqrt m)\),理论上比Dinic优秀。

一般来说不会卡Dinic,但看情况吧(

最小费用最大流

Dinic

对最大流的Dinic做一些修改就好了。

把bfs换成spfa。

这是保证流量最大时的最小费用。

板子
#include<bits/stdc++.h>using namespace std;#define gc getchar
int rd(){int f=1,r=0;char ch=gc();while(!isdigit(ch)){ if(ch=='-') f=-1;ch=gc();}while(isdigit(ch)){ r=(r<<3)+(r<<1)+(ch^48);ch=gc();}return f*r;
}const int maxn=5e3+10,maxm=5e4+10,inf=0x7ffffff;
int n,m,s,t,tot=1,head[maxn],cur[maxn];
int mf,mc,dis[maxn];
bool vis[maxn],inq[maxn];
struct edge{int v,nxt;int c,f;
}e[maxm<<1];void add(int u,int v,int f,int c){e[++tot].v=v;e[tot].f=f;e[tot].c=c;e[tot].nxt=head[u];head[u]=tot;
}bool spfa(){for(int i=1;i<=n;++i) dis[i]=inf,cur[i]=head[i],inq[i]=false;queue<int> q;q.push(s);dis[s]=0;inq[s]=true;while(!q.empty()){int u=q.front();q.pop();inq[u]=false;for(int i=head[u];i;i=e[i].nxt){int v=e[i].v,f=e[i].f,c=e[i].c;if(dis[v]>dis[u]+c&&f){dis[v]=dis[u]+c;if(!inq[v]) q.push(v),inq[v]=true;}}}return dis[t]!=inf;
}int dfs(int u,int fl){if(u==t) return fl;int used=0;vis[u]=true;for(int i=cur[u];i&&fl;i=e[i].nxt){cur[u]=i;int v=e[i].v;int f=min(e[i].f,fl),c=e[i].c;if(!vis[v]&&f&&dis[v]==dis[u]+c){int k=dfs(v,f);e[i].f-=k,e[i^1].f+=k;fl-=k,used+=k;mc+=c*k;}}vis[u]=false;return used;
}void dinic(){while(spfa()){int x=0;while((x=dfs(s,inf))) mf+=x;}
}int main(){n=rd(),m=rd(),s=rd(),t=rd();for(int i=1;i<=m;++i){int u=rd(),v=rd(),f=rd(),c=rd();add(u,v,f,c);add(v,u,0,-c);}dinic();printf("%d %d\n",mf,mc);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/857392.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

某狐畅游24校招-C++开发岗笔试

某狐畅游24校招-C++开发岗笔试 目录某狐畅游24校招-C++开发岗笔试一、单选题二、单选题解析本文题目源来自:[PTA程序设计类实验辅助教学平台](PTA | 程序设计类实验辅助教学平台)一、单选题 1-1 若有说明 int a[2][3]; 则对 a 数组元素的正确引用是 A. a[0][1+1]B. a[1][3]C.…

中电金信参编的《金融分布式系统 术语》等5项团体标准正式发布

近日,由北京金融科技产业联盟归口的《金融分布式系统 术语》《金融分布式系统 参考架构》《金融分布式系统 应用设计原则》《金融分布式系统 技术平台能力要求》和《金融分布式系统 运维能力要求》5项团体标准正式发布和实施。该5项标准由中国金融电子化集团有限公司和国内相关…

Linux U盘挂载和卸载

将u盘挂载到linux 在RHEL6.3中挂载U盘的步骤如下:插入U盘:将U盘插入计算机的USB接口。查看U盘设备:使用命令 fdisk -l 或 lsblk 查看系统中已连接的设备列表,找到U盘对应的设备名,通常以 /dev/sdX 的形式表示,其中 X 是字母,如 /dev/sdb 或 /dev/sdc。此处U盘为sdb1创建…

我的世界服务器搭建教程(兼容Paper和Spigot核心,插件安装等)

注意:该服务器是基于Paper1.20.1核心进行初始化,默认兼容spigot插件。 一、配置JDK环境 二、 服务器核心配置 三、服务器启动 四、加入游戏 现在搭建出来的是原版生存服务器,接下来需要进行安装各种插件,包含登录认证;经济;商店;圈地;传送;多地图等可玩性插件。具体内容请看…

我的世界服务器搭建教程 兼容Paper核心 兼容Spigot核心

注意:该服务器是基于Paper1.20.1核心进行初始化,默认兼容spigot插件。 一、配置JDK环境 二、 服务器核心配置 三、服务器启动 四、加入游戏 现在搭建出来的是原版生存服务器,接下来需要进行安装各种插件,包含登录认证;经济;商店;圈地;传送;多地图等可玩性插件。具体内容请看…

.net framework 4.7.2 winform框架项目升级到.net 8.0项目 界面比列失调问题解决

一、问题发生前:在.net framework 4.7.2 winform框架开发的项目 之前在.net framework 4.7.2 开发的winform项目,在visual studio一打开的时候,虽然界面内有些控件也会失调,但是他会提示“使用100%缩放比例重新启动Visual Studio ”点击“使用100%缩放比例重新启动Visual S…

用DBeaver 新建触发器的步骤

1、选中表,新建触发器 2、 在触发器中,插入声明的SQL 完成

鸿蒙(HarmonyOS)原生AI能力之文本识别

鸿蒙(HarmonyOS)原生AI能力之文本识别 原生智能介绍在之前开发中,很多场景我们是通过调用云端的智能能力进行开发。例如文本识别、人脸识别等。原生即指将一些能力直接集成在本地鸿蒙系统中,通过不同层次的AI能力开放,满足开发者的不同场景下的诉求,降低应用开发门槛,帮助…

管理软件助力四六级:是学习规划师还是提分神器?

一、四六级单词学习的挑战 1.1 单词量庞大,记忆困难 四六级考试涉及的词汇量庞大,其中不仅包含常见的基础单词,还包括一些专业术语、固定搭配等。这些单词对于大部分学生来说,是需要长期积累和不断复习的。由于单词记忆的分散性和碎片化特点,考生很难一口气记住所有单词,…

Linux驱动开发笔记(七):操作系统MMU介绍,操作系统操作寄存器的原理和Demo

前言做过单片机的都知道,写驱动是直接代码设置和读取寄存器来控制外设实现基本的驱动功能,而linux操作系统上是由MMU(内存管理单元)来控制,MMU实现了虚拟地址与芯片物理地址的对应,设置和获取MMU地址就是设置和获取映射的物理地址,从而跟单片机一样实现与物理硬件的驱动…

视频智能分析AI智能分析网关小知识:如何评估和提升视频监控系统的图像质量?

在数字化时代,视频监控系统已成为我们生活中不可或缺的一部分,无论是在公共安全、交通管理还是商业监控等领域,高质量的图像对于监控系统的效能至关重要。随着技术的发展,我们有了更多的工具和方法来评估和提升视频监控系统的图像质量。 本文将探讨如何通过一系列综合措施,…

麒麟系统离线安装部署tomcat

麒麟系统离线安装部署tomcat离线安装部署tomcat下载tomcat 要使用java 11 所以下载tomcat 9 下载链接使用sftp上传到服务器/data/install解压下载的包tar -zxvf apache-tomcat-9.0.98.tar.gz移动文件夹到指定目录mv /data/install/apache-tomcat-9.0.98 /opt/app/tomcat赋予权限…