网络流

网络流强化-HDU2732

孤人 提交于 2019-11-27 15:12:02
  第一次遇到加了“多余”的边会导致WA的——在我看来是很多余,见代码191行   之后会思考为什么,想出来再更。    //http://www.renfei.org/blog/isap.html 带解释的 //https://www.cnblogs.com/bosswnx/p/10353301.html 形式和我的比较相近的 #include<cstdio> #include<cstring> #include<cmath> using namespace std; #define maxe 100024 //pay 双向边 一共10万条路 双向就是20万 反边就是40万 #define maxv 1024 //pay #define maxn 25 //pay #define sc scanf #define pt printf #define rep(i,a,b) for(int i=(a);i<(b);++i) const int inf = 0x3f3f3f3f; int cg,sp,ins; //cg change sp是总流量 ins是加速回溯点 int N,M,T,D ,s,t,delta; int q[maxv],fro,rea; typedef struct ed{ int v,nxt,cap; //dis }ed; ed e[maxe]; int tot

网络流强化-UVA10480

岁酱吖の 提交于 2019-11-27 12:24:29
  做这道题,自己先是想了好几种找被割的边的方法——都被否决了。   后来发现是最小割:只要一条边的两端在不同的点集里面就代表是被割掉的满流边(这些满流边的流量和等于最大流的流量与最小割的权值和)。   但是之前自己想了一个例子,    10 11 1 4 3 4 3 3 3 2 3 4 5 100 5 6 100 6 7 100 7 2 100 1 8 100 8 9 100 9 10 100 10 3 100 0 0   首先这个例子我自己误判了,以为最大流的流量是6,只要割掉1-4和3-2就行——就是脑子短路了,所以我还反过来怀疑双向边,再怀疑DFS和BFS寻找割集的方法,最后居然怀疑最大流和最小割的关系。   后来用了别人的代码,发现我自己解出来的最大流量值错了;但是用自己编的数据(在上面的基础上修改的):    10 11 1 4 3 4 3 3 3 2 3 4 5 3 5 6 100 6 7 100 7 2 100 1 8 100 8 9 100 9 10 100 10 3 100 0 0   她居然给我跑出来了三条容量为3的边,这就是为什么我怀疑最大流和最小割的关系的原因,后来发现人家在寻找源点能到的点集的时候,不仅要求边的剩余流量大于0,还要求基础的cap容量要大于0,这样的做法是错的。修改之后就好了。   AC代码:   //http://www.renfei

网络流强化-HDU4280

旧巷老猫 提交于 2019-11-27 07:03:51
  数组没开够居然显示TLE而不是RE,自己觉得好的优化的方法没什么用……    //http://www.renfei.org/blog/isap.html 带解释的 //https://www.cnblogs.com/bosswnx/p/10353301.html 形式和我的比较相近的 #include<queue> #include<cstdio> #include<cstring> using namespace std; #define maxe 400096 //pay 双向边 一共10万条路 双向就是20万 反边就是40万 #define maxv 100005 //pay #define maxn 55 //pay #define sc scanf #define pt printf #define rep(i,a,b) for(int i=(a);i<(b);++i) const int inf = 0x3f3f3f3f; int cg,sp,ins; //cg change sp是总流量 ins是加速回溯点 int T,N,M ,s,t; int q[maxv],fro,rea; typedef struct ed{ int v,nxt,cap; //dis }ed; ed e[maxe]; int who_is_westernest,who_is

网络流强化-POJ2516

馋奶兔 提交于 2019-11-27 05:09:51
  k种货物分开求解最小费用最大流,主要减少了寻找最短路的时间。    #include<queue> #include<cstdio> #include<cstring> using namespace std; #define maxe 256000 //pay #define maxv 5120 //pay #define maxn 55 //pay #define sc scanf #define pt printf #define rep(i,a,b) for(int i=(a);i<(b);++i) const int inf = 0x3f3f3f3f; int fee,cg,sp,need; int N,M,K ,s,t; typedef struct ed{ int v,nxt,cap,dis; }ed; ed e[maxe]; int nxt[maxe],tot,head[maxv],vis[maxv],d[maxv],bk[maxv]; int mp[maxn][maxn][maxn]; int mi(int a,int b) {return a<b?a:b;} void add(int u,int v,int cap,int dis) { e[tot].v=v; e[tot].nxt=head[u]; e[tot].dis=dis; e[tot].cap

网络流总结

坚强是说给别人听的谎言 提交于 2019-11-27 03:21:30
洛谷 P2756 飞行员配对方案问题 分析 其实就是一个二分图匹配求最大匹配数的问题,加一个源点和汇点,再跑一遍网络流,输出方案的时候检查一下有没有流经过即可(反向边是否非0)。 注意: 每个点在向源点和汇点连边时,要在输入完之后再连。否则会重复连。 #include<bits/stdc++.h> using namespace std; #define N 205 #define M 30005 int to[M],head[N],nex[M],w[M],lev[N],tot=1,cnt=0,inf=0x7f7f7f,s=0,t=101,n,cur[N]; struct node{ int u,v,bian; }e[M]; queue<int> q; void add(int a,int b,int ww) { tot++; to[tot]=b; w[tot]=ww; nex[tot]=head[a]; head[a]=tot; if(ww==0&&b&&a!=t) e[cnt].bian=tot; } bool bfs() { memset(lev,-1,sizeof(lev)); lev[s]=0; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=nex[i]

网络流题目集锦(转)

萝らか妹 提交于 2019-11-27 00:50:03
最大流 POJ 1273 Drainage Ditches POJ 1274 The Perfect Stall (二分图匹配) POJ 1698 Alice's Chance POJ 1459 Power Network POJ 2112 Optimal Milking (二分) POJ 2455 Secret Milking Machine (二分) POJ 3189 Steady Cow Assignment (枚举) POJ 1637 Sightseeing tour (混合图欧拉回路) POJ 3498 March of the Penguins (枚举汇点) POJ 1087 A Plug for UNIX POJ 1149 Pigs (构图题) ZOJ 2760 How Many Shortest Path (边不相交最短路的条数) POJ 2391 Ombrophobic Bovines (必须拆点,否则有BUG) WHU 1124 Football Coach (构图题) SGU 326 Perspective (构图题,类似于 WHU 1124) UVa 563 Crimewave UVa 820 Internet Bandwidth POJ 3281 Dining (构图题) POJ 3436 ACM Computer Factory POJ 2289

方格取数(网络流24题)

久未见 提交于 2019-11-27 00:45:17
题意 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。对于给定的方格棋盘,按照取数要求编程找出总和最大的数。 题解 方格是常见的二分图(疑问脸)。所以考虑先染色,相邻的格子颜色不同,这样就分成了二分图,先假设全选,然后跑最小割就好了,割掉就是不选。 #include<bits/stdc++.h> using namespace std; const int maxn=10005; const int maxm=40005; const int inf=1000009; int n,m,s,t,ans; int cnt=1,head[maxn]; struct edge{ int x,y,next,val; }e[maxm<<1]; void add(int x,int y,int val){ e[++cnt]=(edge){x,y,head[x],val}; head[x]=cnt; } void add_edge(int x,int y,int val){ add(x,y,val); add(y,x,0); } template<class T>inline void read(T &x){ x=0;char ch=getchar(); while(!isdigit

【网络流】——P1251 餐巾计划问题

元气小坏坏 提交于 2019-11-27 00:23:41
网络流的应用太多了,对于各种网络流的题目,要熟练运用建模思想,将实际问题转化为网络流模型。 GO: 洛谷 我们将问题划分成几个子问题:   1.“餐巾的数量”,“需要的费用”,“天数”分别指代什么?   2.快洗,慢洗会对哪些状态造成影响?   3.如何建立(记录)影响与影响间的关系   …… 首先,分析题意,不难发现这是一道最小费用最大流的问题。我们按贪心的思想看,每天分配好所需要的餐巾是基本任务,而让所花的费用最小是优化方案。 因此,分配餐巾对应着网络中的流,而费用就是费用。 快洗,慢洗等状态会为未来的某一天增加餐巾,因此影响的对象是未来洗完的那一天。 我们将一天分为两个状态:消耗餐巾和送出餐巾。 消耗餐巾,在网络流中即为消耗流(使用餐巾),而送出对应着增加花费(洗餐巾),这样就将模型初步建立完成了。 而对于程序本身而言,一个流为inf的边,代表可以随便走,最终这条边也不会被删去,但是只要走过了就会消耗费用,比如将今天的餐巾送出去洗。而一个流为0,费用为0的边,可以当做一个状态的转移,比如将今天的餐巾堆积到明天,既不消耗费用也不使用餐巾。所以限制好一些条件,让程序自己完成任务即可,这是网络流最大的魅力所在。 1 #include<bits/stdc++.h> 2 #define f(i,a,b) for(int i=a;i<=b;i++) 3 using namespace

【网络流】——最小费用最大流EK算法

一笑奈何 提交于 2019-11-27 00:04:12
本文非原创, 大 部分参考自 秋日私语 大大的题解。 GO: 模板    最大流问题,我们可以通过EK,DINIC等方法解决,但是如果在每条边上加上边权,并定义 费用 为边权乘以流量,在所有最大流中求出费用最少的那一个方案,就需要新的算法了。   这里只对最小费用最大流的EK-SPFA算法做一些自己的解释,并会附上模板。 首先是EK算法:   1.我们每次求一条源点到汇点的路径,流量最大为路径上的最小流量minflow,所以下一次寻找最大流就不能走那条,于是将所有边的流量减小minflow。   2.由1能保证求出最大流吗?答案是否定的,因为当我们遇到一些特殊的图时:    比如这个,第一条路径S-2-T,边上流量变为0,得到maxflow=4,实际上maxflow=6,因此我们要加一条反向边让路径有“反悔”的机会。   3.我们使用bfs进行增广,这样能保证在更少的次数下求出最大流。   4.对2具体的操作:记录路径上每个点的前驱和前驱边,走完spfa后从后向前遍历前驱边,修改流量。 最小费用最大流:    众所周知,SPFA他死了。   但这并不影响我们做网络流的题目(出题人没必要在网络流的题目上用图论卡我们),我们借鉴spfa的思想,对路径上求最短路。   具体看代码。 1 //EK-MCMF 2 #include<bits/stdc++.h> 3 using

图论之点双&边双

回眸只為那壹抹淺笑 提交于 2019-11-26 22:43:48
说人话: 边双联通: a到b的路径上无必经边 点双联通: a到b的路径上除了a,b没有必经点 tarjan求点双联通: 代码(补图) 割点: 桥: 求点双:强制dfs时不越过割点,即可求出一个块 求边双:dfs时不越过桥 不是割点:减少2n-1 是割点:减少sigmai的大小*其他所有子树的大小 tarjan求桥,然后缩点,会形成一棵树。把树的所有叶子连起来用的边数就是答案 判断: 当且仅当无向图上不含奇环的时候就是二分图 增广路特点:非匹配边比匹配边多一条 寻找增广路:dfs 咕咕咕~ 网络流: 最小割最大流定理:网络流的最大流就是整个图的最小割 dinic:类似匈牙利算法的思路,不断寻找当前最大流能加1的方案 直到不能再加 先dfs一遍,确定每个点到源点s的距离, 同时不断加边,维护当前流量 毒瘤操作:减少某条边的流量 所以就减反向边,边权为0,表示从终点到起点可扩充流量 二分图最大匹配怎么用网络流搞? 在左边建一个超级源点s,在右边建一个超级汇点t s向每个左边的点建一个流量为1的边,右边的点向t建流量为1的边 二分图中间的点不停的寻找能加流量的路,能加就加,知道不能加 总之最大流就是最大匹配 二分图建图小技巧: 如果有x轴,y轴,且有一个坐标(x0,y0) 则就由x0向y0建一条边 国际象棋棋盘:黑白染色(黑的向白的建边) 就是最小覆盖qwq