网络流 最大流SAPkuangbin模板
hdu 1532 求1~n的最大流
- #include<stdio.h>
- #include<string.h>
- #include<algorithm>
- #include<iostream>
- using namespace std;
- const int MAXN = ; //点数的最大值
- const int MAXM = ; //边数的最大值
- const int INF = 0x3f3f3f3f;
- struct Node
- {
- int from, to, next;
- int cap;
- } edge[MAXM];
- int tol;
- int head[MAXN];
- int dep[MAXN];
- int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y
- int n;//n是总的点的个数,包括源点和汇点
- void init()
- {
- tol = ;
- memset(head, -, sizeof(head));
- }
- void addedge(int u, int v, int w)
- {
- edge[tol].from = u;
- edge[tol].to = v;
- edge[tol].cap = w;
- edge[tol].next = head[u];
- head[u] = tol++;
- edge[tol].from = v;
- edge[tol].to = u;
- edge[tol].cap = ;
- edge[tol].next = head[v];
- head[v] = tol++;
- }
- void BFS(int start, int end)
- {
- memset(dep, -, sizeof(dep));
- memset(gap, , sizeof(gap));
- gap[] = ;
- int que[MAXN];
- int front, rear;
- front = rear = ;
- dep[end] = ;
- que[rear++] = end;
- while (front != rear)
- {
- int u = que[front++];
- if (front == MAXN)
- {
- front = ;
- }
- for (int i = head[u]; i != -; i = edge[i].next)
- {
- int v = edge[i].to;
- if (dep[v] != -)
- {
- continue;
- }
- que[rear++] = v;
- if (rear == MAXN)
- {
- rear = ;
- }
- dep[v] = dep[u] + ;
- ++gap[dep[v]];
- }
- }
- }
- int SAP(int start, int end)
- {
- int res = ;
- BFS(start, end);
- int cur[MAXN];
- int S[MAXN];
- int top = ;
- memcpy(cur, head, sizeof(head));
- int u = start;
- int i;
- while (dep[start] < n)
- {
- if (u == end)
- {
- int temp = INF;
- int inser;
- for (i = ; i < top; i++)
- if (temp > edge[S[i]].cap)
- {
- temp = edge[S[i]].cap;
- inser = i;
- }
- for (i = ; i < top; i++)
- {
- edge[S[i]].cap -= temp;
- edge[S[i] ^ ].cap += temp;
- }
- res += temp;
- top = inser;
- u = edge[S[top]].from;
- }
- if (u != end && gap[dep[u] - ] == ) //出现断层,无增广路
- {
- break;
- }
- for (i = cur[u]; i != -; i = edge[i].next)
- if (edge[i].cap != && dep[u] == dep[edge[i].to] + )
- {
- break;
- }
- if (i != -)
- {
- cur[u] = i;
- S[top++] = i;
- u = edge[i].to;
- }
- else
- {
- int min = n;
- for (i = head[u]; i != -; i = edge[i].next)
- {
- if (edge[i].cap == )
- {
- continue;
- }
- if (min > dep[edge[i].to])
- {
- min = dep[edge[i].to];
- cur[u] = i;
- }
- }
- --gap[dep[u]];
- dep[u] = min + ;
- ++gap[dep[u]];
- if (u != start)
- {
- u = edge[S[--top]].from;
- }
- }
- }
- return res;
- }
- int main()
- {
- // freopen("in.txt","r",stdin);
- // freopen("out.txt","w",stdout);
- int start, end;
- int m;
- int u, v, z;
- int T;
- while (~scanf("%d%d", &m, &n))
- {
- init();
- while (m--)
- {
- scanf("%d%d%d", &u, &v, &z);
- addedge(u, v, z);
- //addedge(v, u, z);
- }
- //n一定是点的总数,这是使用SAP模板需要注意的
- int ans = SAP(, n);
- printf("%d\n", ans);
- }
- return ;
- }
hdu 4280 给你岛的坐标求最西边到最东边的最大流
- /*
- 最大流模板
- sap
- */
- #include<stdio.h>
- #include<string.h>
- #include<algorithm>
- #include<iostream>
- using namespace std;
- const int MAXN=;//点数的最大值
- const int MAXM=;//边数的最大值
- const int INF=0x3f3f3f3f;
- struct Node
- {
- int from,to,next;
- int cap;
- }edge[MAXM];
- int tol;
- int head[MAXN];
- int dep[MAXN];
- int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y
- int n;//n是总的点的个数,包括源点和汇点
- void init()
- {
- tol=;
- memset(head,-,sizeof(head));
- }
- void addedge(int u,int v,int w)
- {
- edge[tol].from=u;
- edge[tol].to=v;
- edge[tol].cap=w;
- edge[tol].next=head[u];
- head[u]=tol++;
- edge[tol].from=v;
- edge[tol].to=u;
- edge[tol].cap=;
- edge[tol].next=head[v];
- head[v]=tol++;
- }
- void BFS(int start,int end)
- {
- memset(dep,-,sizeof(dep));
- memset(gap,,sizeof(gap));
- gap[]=;
- int que[MAXN];
- int front,rear;
- front=rear=;
- dep[end]=;
- que[rear++]=end;
- while(front!=rear)
- {
- int u=que[front++];
- if(front==MAXN)front=;
- for(int i=head[u];i!=-;i=edge[i].next)
- {
- int v=edge[i].to;
- if(dep[v]!=-)continue;
- que[rear++]=v;
- if(rear==MAXN)rear=;
- dep[v]=dep[u]+;
- ++gap[dep[v]];
- }
- }
- }
- int SAP(int start,int end)
- {
- int res=;
- BFS(start,end);
- int cur[MAXN];
- int S[MAXN];
- int top=;
- memcpy(cur,head,sizeof(head));
- int u=start;
- int i;
- while(dep[start]<n)
- {
- if(u==end)
- {
- int temp=INF;
- int inser;
- for(i=;i<top;i++)
- if(temp>edge[S[i]].cap)
- {
- temp=edge[S[i]].cap;
- inser=i;
- }
- for(i=;i<top;i++)
- {
- edge[S[i]].cap-=temp;
- edge[S[i]^].cap+=temp;
- }
- res+=temp;
- top=inser;
- u=edge[S[top]].from;
- }
- if(u!=end&&gap[dep[u]-]==)//出现断层,无增广路
- break;
- for(i=cur[u];i!=-;i=edge[i].next)
- if(edge[i].cap!=&&dep[u]==dep[edge[i].to]+)
- break;
- if(i!=-)
- {
- cur[u]=i;
- S[top++]=i;
- u=edge[i].to;
- }
- else
- {
- int min=n;
- for(i=head[u];i!=-;i=edge[i].next)
- {
- if(edge[i].cap==)continue;
- if(min>dep[edge[i].to])
- {
- min=dep[edge[i].to];
- cur[u]=i;
- }
- }
- --gap[dep[u]];
- dep[u]=min+;
- ++gap[dep[u]];
- if(u!=start)u=edge[S[--top]].from;
- }
- }
- return res;
- }
- int main()
- {
- // freopen("in.txt","r",stdin);
- // freopen("out.txt","w",stdout);
- int start,end;
- int m;
- int u,v,z;
- int T;
- scanf("%d",&T);
- while(T--)
- {
- init();
- scanf("%d%d",&n,&m);
- int minx=;
- int maxx=-;
- int x,y;
- for(int i=;i<=n;i++)
- {
- scanf("%d%d",&x,&y);
- if(minx>x)
- {
- minx=x;
- start=i;
- }
- if(maxx<x)
- {
- maxx=x;
- end=i;
- }
- }
- while(m--)
- {
- scanf("%d%d%d",&u,&v,&z);
- addedge(u,v,z);
- addedge(v,u,z);
- }
- //n一定是点的总数,这是使用SAP模板需要注意的
- int ans=SAP(start,end);
- printf("%d\n",ans);
- }
- return ;
- }
网络流 最大流SAPkuangbin模板的更多相关文章
- 网络流--最大流dinic模板
标准的大白书式模板,除了变量名并不一样……在主函数中只需要用到 init 函数.add 函数以及 mf 函数 #include<stdio.h> //差不多要加这么些头文件 #includ ...
- 网络流--最大流ek模板
标准大白书式模板,代码简单但由于效率并不高,所以并不常用,就是这样 #include<stdio.h> #include<string.h> #include<queue ...
- 网络流-最大流 Dinic模板
#include <bits/stdc++.h> using namespace std; #define MP make_pair #define PB push_back #defin ...
- 网络流--最大流--Dinic模板矩阵版(当前弧优化+非当前弧优化)
//非当前弧优化版 #include <iostream> #include <cstdio> #include <math.h> #include <cst ...
- 网络流--最大流--EK模板
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- (通俗易懂小白入门)网络流最大流——EK算法
网络流 网络流是模仿水流解决生活中类似问题的一种方法策略,来看这么一个问题,有一个自来水厂S,它要向目标T提供水量,从S出发有不确定数量和方向的水管,它可能直接到达T或者经过更多的节点的中转,目前确定 ...
- HDU1532 网络流最大流【EK算法】(模板题)
<题目链接> 题目大意: 一个农夫他家的农田每次下雨都会被淹,所以这个农夫就修建了排水系统,还聪明的给每个排水管道设置了最大流量:首先输入两个数n,m ;n为排水管道的数量,m为节点的数量 ...
- [POJ1273][USACO4.2]Drainage Ditches (网络流最大流)
题意 网络流最大流模板 思路 EK也不会超时 所以说是一个数据比较水的模板题 但是POJ有点坑,多组数据,而且题目没给 哭得我AC率直掉 代码 用的朴素Dinic #include<cstdio ...
- [讲解]网络流最大流dinic算法
网络流最大流算法dinic ps:本文章不适合萌新,我写这个主要是为了复习一些细节,概念介绍比较模糊,建议多刷题去理解 例题:codevs草地排水,方格取数 [抒情一下] 虽然老师说这个多半不考,但是 ...
随机推荐
- 如何使用Jetbrains Clion 在一个工程里 编译单个C++源文件 (实现一键编译且运行)
这篇文章主要在下面这篇文章的基础上,先是实现了一键编译和一键运行两个单个功能,最后又进一步使用Clion自带的Custom Build Application实现编译且运行一键实现. https:// ...
- leetcode234 回文链表 两种做法(stack(空间非O(1)),空间O(1))
link: leetcode234 回文链表 方法1, 快慢指针,把前半部分存入栈中和后半部分比较 public boolean isPalindrome(ListNode head) { if(he ...
- HTTP学习记录:二、请求方法
学习资源主要为:@小坦克HTTP相关博客 最基础的是4种,GET.POST.PUT.DELETE对应着对资源的查.改.增.删.最常用的是GET和POST. GET一般用于获取/查询资源信息: POST ...
- c++ 事件回调 java
#pragma once #ifdef __cplusplus extern "C" { #endif typedef void(*sig_t)(int); int FirstEl ...
- sentos7忘记root密码,重置密码
一.两种模式:单用户模式和救援模式 下面示例救援模式 1.重启linux系统主机并出现引导界面,按e键进入内核编辑界面: 2.在linux16参数那一行的最后面追加“rd.break”参数,记住要空开 ...
- 【Qt开发】foreach用法
If you just want to iterate over all the items in a container in order, you can use Qt's foreach key ...
- 【Qt开发】Linux下Qt开发环境的安装与集成
近期工作需要在Linux下用Qt进行C++开发,所以就在linux下尝试装QT开发环境.本人用的linux是CentOS 6.5.现在对安装过程做出总结.有两种安装方式,下面分别详述: 1 图形化安装 ...
- 使用原生js 获取用户访问项目的浏览器类型
想要获取浏览器的类型很简单,网上提供了很多方法,但是看过之后,都是根据浏览器内核来判断是ie,谷歌,火狐,opeara的, 所以不能进一步判断在国内使用的主流浏览器类型,比如360,百度,搜狐浏览器等 ...
- Java中类和接口
很形象的接口的使用——针对初学者 里氏代换原则是什么?听起来很高深,不过我们也不是什么学院派,就不讲大道理了,直接拿个例子来说一下. 我们拿人和程序员举个例子.人是一个大类,程序员是继承自人的子类.看 ...
- Java合并数组的实现方式
String[] aa = {"11","22","33"};String[] bb = {"44","55& ...