wenbao与网络流

最大流(推荐博客http://blog.csdn.net/mystery_guest/article/details/51910913)

不断增广

SAP模板

  1 const int MAXN = 20010;//点数的最大值
  2 const int MAXM = 880010;//边数的最大值
  3 const int INF = 0x3f3f3f3f;
  4
  5 struct Node{
  6     int from, to, next;
  7     int cap;
  8 }edge[MAXM];
  9 int tol;
 10 int head[MAXN];
 11 int dep[MAXN];
 12 int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y
 13
 14 int n;//n是总的点的个数,包括源点和汇点
 15
 16 void init(){
 17     tol = 0;
 18     memset(head, -1, sizeof(head));
 19 }
 20
 21 void addedge(int u, int v, int w){
 22     edge[tol].from = u;
 23     edge[tol].to = v;
 24     edge[tol].cap = w;
 25     edge[tol].next = head[u];
 26     head[u] = tol++;
 27     edge[tol].from = v;
 28     edge[tol].to = u;
 29     edge[tol].cap = 0;
 30     edge[tol].next = head[v];
 31     head[v] = tol++;
 32 }
 33
 34 void BFS(int start, int end){
 35     memset(dep, -1, sizeof(dep));
 36     memset(gap, 0, sizeof(gap));
 37     gap[0] = 1;
 38     int que[MAXN];
 39     int front = 0, rear = 0;
 40     dep[end] = 0;
 41     que[rear++] = end;
 42     while(front != rear){
 43         int u = que[front++];
 44         if(front == MAXN) front = 0;
 45         for(int i = head[u]; i !=- 1; i = edge[i].next){
 46             int v = edge[i].to;
 47             if(dep[v] != -1)continue;
 48             que[rear++] = v;
 49             if(rear == MAXN) rear = 0;
 50             dep[v] = dep[u] + 1;
 51             ++gap[dep[v]];
 52         }
 53     }
 54 }
 55
 56 int SAP(int start, int end){
 57     int res = 0;
 58     BFS(start, end);
 59     int cur[MAXN];
 60     int S[MAXN];
 61     int top = 0;
 62     memcpy(cur, head, sizeof(head));
 63     int u = start;
 64     int i;
 65     while(dep[start] < n){
 66         if(u == end){
 67             int temp = INF;
 68             int inser;
 69             for(i = 0; i < top; i++) if(temp > edge[S[i]].cap){
 70                 temp = edge[S[i]].cap;
 71                 inser = i;
 72             }
 73             for(i = 0; i < top; i++){
 74                 edge[S[i]].cap -= temp;
 75                 edge[S[i]^1].cap += temp;
 76             }
 77             res += temp;
 78             top = inser;
 79             u = edge[S[top]].from;
 80         }
 81         if(u != end && gap[dep[u]-1] == 0)//出现断层,无增广路
 82           break;
 83         for(i = cur[u]; i != -1; i = edge[i].next)
 84            if(edge[i].cap != 0 && dep[u] == dep[edge[i].to] + 1)
 85              break;
 86         if(i != -1){
 87             cur[u] = i;
 88             S[top++] = i;
 89             u = edge[i].to;
 90         }else{
 91             int min = n;
 92             for(i = head[u]; i != -1; i = edge[i].next){
 93                 if(edge[i].cap == 0) continue;
 94                 if(min > dep[edge[i].to]){
 95                     min = dep[edge[i].to];
 96                     cur[u] = i;
 97                 }
 98             }
 99             --gap[dep[u]];
100             dep[u] = min+1;
101             ++gap[dep[u]];
102             if(u != start) u = edge[S[--top]].from;
103         }
104     }
105     return res;
106 }

只有不断学习才能进步!

原文地址:https://www.cnblogs.com/wenbao/p/7500305.html

时间: 2024-10-25 20:10:46

wenbao与网络流的相关文章

hiho 第118周 网络流四&#183;最小路径覆盖

描述 国庆期间正是旅游和游玩的高峰期. 小Hi和小Ho的学习小组为了研究课题,决定趁此机会派出若干个调查团去沿途查看一下H市内各个景点的游客情况. H市一共有N个旅游景点(编号1..N),由M条单向游览路线连接.在一个景点游览完后,可以顺着游览线路前往下一个景点. 为了避免游客重复游览同一个景点,游览线路保证是没有环路的. 每一个调查团可以从任意一个景点出发,沿着计划好的游览线路依次调查,到达终点后再返回.每个景点只会有一个调查团经过,不会重复调查. 举个例子: 上图中一共派出了3个调查团: 1

POJ2584 T-Shirt Gumbo 二分图匹配(网络流)

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 const int inf=0x3f3f3f3f; 6 const int sink=30; 7 8 struct Edge 9 { 10 int to; 11 int next; 12 int capacity; 13 14 void assign(int t,int n,int c) 15 { 16 to=t; next=n; ca

UVA 1306 - The K-League(网络流)

UVA 1306 - The K-League 题目链接 题意:n个球队,已经有一些胜负场,现在还有一些场次,你去分配胜负,问每支球队有没有可能获胜 思路:网络流公平分配模型,把场次当作任务,分配给人,然后先贪心,枚举每个人,让这些人能赢的都赢,剩下的去建图,每个源点连向比赛容量为场次,每个比赛连向2个球队,容量无限大,每个球队连向汇点,容量为每个的人的总和减去当前已经赢的,建完图跑一下最大流,然后判断源点流出的是否都满流即可 代码: #include <cstdio> #include &l

hdu 4975 A simple Gaussian elimination problem.(网络流,判断矩阵是否存在)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4975 Problem Description Dragon is studying math. One day, he drew a table with several rows and columns, randomly wrote numbers on each elements of the table. Then he counted the sum of each row and col

POJ训练计划3422_Kaka&#39;s Matrix Travels(网络流/费用流)

解题报告 题目传送门 题意: 从n×n的矩阵的左上角走到右下角,每次只能向右和向下走,走到一个格子上加上格子的数,可以走k次.问最大的和是多少. 思路: 建图:每个格子掰成两个点,分别叫"出点","入点", 入点到出点间连一个容量1,费用为格子数的边,以及一个容量∞,费用0的边. 同时,一个格子的"出点"向它右.下的格子的"入点"连边,容量∞,费用0. 源点向(0,0)的入点连一个容量K的边,(N-1,N-1)的出点向汇点连一

HDU 3488Tour(网络流之最小费用流)

题目地址:hdu3488 这题跟上题基本差不多啊....详情请戳这里. 另外我觉得有要改变下代码风格了..终于知道了为什么大牛们的代码的变量名都命名的那么长..我决定还是把源点与汇点改成source和sink吧..用s和t太容易冲突了...于是如此简单的一道题调试到了现在..sad... 代码如下: #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #

LibreOJ #6002. 「网络流 24 题」最小路径覆盖

内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:Special Judge 上传者: 匿名 网络流 最大流 屠龙宝刀点击就送 #include <cstring> #include <cstdio> #include <queue> #define N 6005 #define inf 0x3f3f3f3f using namespace std; bool flag[N]; int n,m,dep[N],nextt[N<

POJ 1273 Drainage Ditches (网络流Dinic模板)

Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer John has built a set of drainage

网络流(进阶)

最大流:DINIC or SAP 最小费用最大流:SPFA+增广(费用的值较离散) or ZKW(费用的值集中) 有源汇的上下界最大流:新建s', t',用(i, j, l, r)表示i到j有一条下界为l上界为r的边,将每条这样的边拆成(s', j, 0, l), (i, t', 0, l), (i, j, 0, r-l),加入边(t, s, 0, max)再从s'到t'求最大流,再去掉(t, s, 0, max)这条边,从s到t求最大流 有源汇的上下界最小可行流:基本同上,将最后一步改成从t到