洛谷P3376-网络流
模板题,但是数据加强过了,朴素的Dinic跑这道题会T2个点,但是FF算法却可以轻松过
还是挺神奇的
Dinic+弧优化+剪枝
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <functional>
#include <vector>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
const int maxn=200+50;
const int inf=0x7fffffff;
const int MOD=998244353;
const int HASH=131;int n, m, cnt;//点,边,前向星计数
int head[maxn];//前向星
int level[maxn];//分层
int cur[maxn];//当前弧优化struct Edge
{int to;ll val;int next;
}edge[maxn*maxn];void add(int u,int v,int val)
{edge[cnt].to=v;edge[cnt].val=val;edge[cnt].next=head[u];head[u]=cnt++;
/*反向存边,在原边基础上+1*/edge[cnt].to=u;edge[cnt].val=0;edge[cnt].next=head[v];head[v]=cnt++;
}bool find_level(int s,int t)//源点和汇点,该bfs函数用来确定深度(层次)
{queue<int> q;memset(level,0,sizeof(level));for(int i=1;i<=n;i++){cur[i]=head[i];}int u=s;level[u]=1;q.push(u);while(!q.empty()){u=q.front();q.pop();for(int i=head[u];~i;i=edge[i].next){int v=edge[i].to;ll val=edge[i].val;if(!level[v]&&val)//层次不为0且容量不为0{level[v]=level[u]+1;q.push(v);}}if(level[t])//如果t有分层则继续下一步的处理{return true;}}return false;
}ll updata(int u,ll u_val,int t)//dfs更新
{if(u==t){return u_val;}ll used=0;//使用多少容量for(int &i=cur[u];~i;i=edge[i].next)//当前弧优化的神奇操作,{int v=edge[i].to;ll val=edge[i].val;if(level[v]==level[u]+1&&val)//如果是相邻两层且有剩余容量{ll tmp=updata(v,min(u_val-used,val),t);//dfs递归,找最小容量edge[i].val-=tmp;edge[i^1].val+=tmp;used+=tmp;if(used==u_val) return used;//达到最大值,本条增广路作废?}}if(used==0) level[u]=-1;//找不到增广路,减枝,节点作废return used;
}ll Dinic(int s,int t)
{ll ans=0;while(find_level(s,t)){ans+=updata(s,inf,t);}return ans;
}void init()
{cnt=0;memset(head,-1,sizeof(head));
}int main()
{init();int s,t;scanf("%d %d %d %d",&n,&m,&s,&t);for(int i =1;i<=m;i++){ll a,b,c;scanf("%lld %lld %lld",&a,&b,&c);add(a,b,c);}printf("%lld",Dinic(s,t));return 0;
}
朴素FF
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <functional>
#include <vector>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
const int maxn=2e5+50;
const int inf=0x3f3f3f3f;
const int MOD=998244353;
const int HASH=131;ll edge[208][208];
int pre[208];//记录前驱结点
int vis[208];//判断是否跑过
int n,m;//结点数 边数
int s,t;//s为源点 t为汇点
ll flow;//最大流bool findpath()//bfs找增广路径
{queue<int> q;memset(vis,0,sizeof(vis));memset(pre,-1,sizeof(pre));vis[s]=1;q.push(s);//跑前驱结点while(!q.empty()){ll tmp=q.front();q.pop();for(int i=1;i<=n;i++){if(vis[i]==0&&edge[tmp][i]>0){pre[i]=tmp;//记录前驱结点vis[i]=1;//本次是否跑过,防止出现环q.push(i);if(i==t) return true;}}}return false;
}bool change()//更新
{if(findpath()==false) //没有增广路则直接结束,此时的flow就是最大流{return false;}ll minn=edge[pre[t]][t];//最小残差路(上一增广路的流)for(int i=t;i!=s;i=pre[i]){minn=min(edge[pre[i]][i],minn);//类似前向星,反复调用找到最小残差路}for(int i=t;i!=s;i=pre[i])//更新残图{edge[pre[i]][i]-=minn;edge[i][pre[i]]+=minn;}flow+=minn;return true;
}int main()
{int x;scanf("%d %d %d %d",&n,&m,&s,&t);for(int i=1;i<=m;i++){int a,b,tmp;scanf("%d %d %d",&a,&b,&tmp);edge[a][b]+=tmp;}while(change());printf("%lld",flow);return 0;
}
洛谷P3376-网络流相关推荐
- 洛谷P3376 网络最大流
不是讲网络流,就是存个板子 另外我的Dinic跑得比EK慢一倍可还行( 附两份比较好的教程,均来自洛谷日报 EK\sf \color{blue}EKEK Dinic\sf \color{blue}Di ...
- 【洛谷P3376】网络最大流【网络流】
分析 网络流算法本身是之前学过的,今天拿出来复习打个板子. 最原始的思路应该是搜索每一条路,每次进行增广的操作,知道不能增广为止.显然,这种思路复杂度比较高. 如何进行优化?就是dinic算法.上面那 ...
- 洛谷P3376 【模板】网络最大流
P3376 [模板]网络最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点 ...
- 洛谷 P3376 【模板】网络最大流
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- [洛谷P4012] [网络流24题] 深海机器人问题
Description 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生 ...
- 【洛谷 - P3376 】【模板】网络最大流
题干: 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包 ...
- 网络流建模方法(四)—— 互不攻击问题 洛谷 P3353 骑士共存问题 (附 洛谷 P2774 方格取数问题)
网络流建模方法(四)互不攻击问题,或者说是共存问题, 这类题目看起来有点像二分图匹配,这类题目我们就是建一个二分图然后跑最大流 还是先说题目洛谷P3353 题目描述 在一个 nn个方格的国际象棋棋盘上 ...
- 图论--网络流--最大流 洛谷P4722(hlpp)
题目描述 给定 nn 个点,mm 条有向边,给定每条边的容量,求从点 ss 到点 tt 的最大流. 输入格式 第一行包含四个正整数nn.mm.ss.tt,用空格分隔,分别表示点的个数.有向边的个数.源 ...
- 网络流建图方法(二)——辅助点(虚点)决策法洛谷 P1361 小M 的作物 Dinic
inic声明:本博客默认读者会最大流最小割的定理,会Dinic, 最小割在数值上 == 最大流 但是在意义上没有任何关系,姑且可以这样求得最小割,当然可以自行百度最小割的证明定理 还是从题目开始说起 ...
- 洛谷P3386:网络流之二分图匹配,最大流算法
二分图:我的理解是,对图中的点集,可分为两个集合U和V,使得两个集合之间存在通路,且集合内部不存在通路.如上图. 匹配:两两不含公共端点的边集合M 最大匹配:边数最多的匹配 完美匹配:最大匹配的匹配数 ...
最新文章
- 树链剖分——线段树区间合并bzoj染色
- 精选一套火爆B站的硬核资源,请笑纳!
- Android px、dp、sp之间相互转换
- rest-framework 视图
- 3.4_函数_Function_Part_2
- bits/stdc++.h头文件总结
- 使用SAP Analytics Cloud显示新冠肺炎病毒感染人数的实时信息
- 计算机怎么查看U盘品牌,如何查看电脑u盘使用
- 每次登陆都要滑动验证_湖人队冠军成员卡鲁索很吃香:每次谈判都有N支球队点名要他...
- w7计算机不显示移动硬盘,win7系统不显示移动硬盘怎么回事_win7移动硬盘在电脑上显示不出来如何处理-win7之家...
- Leetcode 142. Linked List Cycle IIJAVA语言
- CS 客户端不引用AE
- JS实现报表标题动态滚动效果
- Unity Behaviors for Interception
- 20个常用模拟电路(嵌入式硬件篇)
- 项目经理不得不知道的里程碑计划及其重要用途
- 机器人领域的会议和期刊【补充】
- Java开发需要学什么!中原银行java面试题目
- 移动app需求分析与用例设计
- Hey Future!