OIer-Dinic

 1 class Network  {
 2 private :
 3     struct edge  {
 4         int to, w, nxt ;
 5         edge ( ) {        }
 6         edge ( int to, int w, int nxt ) : to ( to ), w ( w ), nxt ( nxt ) {        }
 7     } g [N << 1] ;
 8
 9     int head [N], cur [N], ecnt ;
10     int S, T , dep [N] ;
11
12     inline int Dfs ( int u, int a )  {
13         if ( u == T || ! a )  return a ;
14         int flow = 0, v, f ;
15         for ( int& i = cur [u] ; i ; i = g [i].nxt )  {
16             v = g [i].to ;
17             if ( dep [v] == dep [u] + 1 )  {
18                 f = Dfs ( v, min ( g [i].w, a - flow ) ) ;
19                 g [i].w -= f, g [i ^ 1].w += f ;
20                 flow += f ;
21                 if ( a == flow )  return a ;
22             }
23         }
24         if ( ! flow )  dep [u] = -1 ;
25         return flow ;
26     }
27
28     inline bool Bfs ( int S, int T )  {
29         static std :: queue < int > q ;
30         memset ( dep, 0, sizeof ( int ) * ( T + 1 ) ) ;
31         dep [S] = 1 ;
32         q.push ( S ) ;
33         while ( ! q.empty ( ) )  {
34             int u = q.front ( ) ;  q.pop ( ) ;
35             for ( int i = head [u] ; i ; i = g [i].nxt )  {
36                 int v = g [i].to ;
37                 if ( g [i].w &&  ! dep [v] )  {
38                     dep [v] = dep [u] + 1 ;
39                     q.push ( v ) ;
40                 }
41             }
42         }
43         return dep [T] ;
44     }
45 public :
46     Network ( )  {    ecnt = 1 ; }
47
48     inline void Add_edge ( int u, int v, int w )  {
49         g [++ ecnt] = edge ( v, w, head [u] ) ;     head [u] = ecnt ;
50         g [++ ecnt] = edge ( u, 0, head [v] ) ;     head [v] = ecnt ;
51     }
52
53     inline int Dinic ( int S, int T )  {
54         this -> S = S, this -> T = T ;
55         int rt = 0 ;
56         while ( Bfs ( S, T ) )    {
57             memcpy ( cur, head, sizeof ( int ) * ( T + 1 ) ) ;
58             rt += Dfs ( S, 0x3f3f3f3f ) ;
59         }
60         return rt ;
61     }
62 } Lazer ;

Class

时间: 2024-10-22 03:41:08

OIer-Dinic的相关文章

网络最大流算法—Dinic算法及优化

前置知识 网络最大流入门 前言 Dinic在信息学奥赛中是一种最常用的求网络最大流的算法. 它凭借着思路直观,代码难度小,性能优越等优势,深受广大oier青睐 思想 $Dinic$算法属于增广路算法. 它的核心思想是:对于每一个点,对其所连的边进行增广,在增广的时候,每次增广“极大流” 这里有别于EK算法,EK算法是从边入手,而Dinic算法是从点入手 在增广的时候,对于一个点连出去的边都尝试进行增广,即多路增广 Dinic算法还引入了分层图这一概念,即对于$i$号节点,用$dis(i)$表示它

poj3436--ACM Computer Factory(最大流,拆点dinic)

ACM Computer Factory Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5501   Accepted: 1887   Special Judge Description As you know, all the computers used for ACM contests must be identical, so the participants compete on equal terms. Th

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算法

dinic算法用于解决最大流问题. 注意每次BFS之前把dist数组清空,源点的dist设为1. 1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #define inf 1000000000 5 using namespace std; 6 int ans,tot,vert,edg,S,T,fr[100005],to[200005],nxt[200005],f[200005]; 7 int

hihoCoder 1393 网络流三&#183;二分图多重匹配(Dinic求二分图最大多重匹配)

#1393 : 网络流三·二分图多重匹配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含小Hi和小Ho),编号依次为1..N. 运动会一共有M项不同的比赛,编号为1..M.第i项比赛每个班需要派出m[i]名选手参加. 根据小Hi和小Ho的统计,编号为i的学生表示最多同时参加

Dinic 模板

1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 6 using namespace std; 7 const int INF=2147483647; 8 const int maxn=210,maxm=410; 9 int cnt,fir[maxn],nxt[maxm],cap[maxm],to[maxm],dis[maxn]; 10 11

算法模板——Dinic网络最大流 2

实现功能:同Dinic网络最大流 1 这个新的想法源于Dinic费用流算法... 在费用流算法里面,每次处理一条最短路,是通过spfa的过程中就记录下来,然后顺藤摸瓜处理一路 于是在这个里面我的最大流也采用这种模式,这样子有效避免的递归,防止了爆栈么么哒 1 type 2 point=^node; 3 node=record 4 g,w:longint; 5 next,anti:point; 6 end; 7 var 8 i,j,k,l,m,n,s,t,flow:longint; 9 a,e:a

网络流 dinic

1 struct Edge { 2 int v, w; 3 int next; 4 }edge[250*250]; 5 int head[50], tot; 6 void addedge(int u, int v, int w) { 7 edge[tot].v = v; 8 edge[tot].w = w; 9 edge[tot].next = head[u]; 10 head[u] = tot++; 11 } 12 int lvl[305]; 13 bool bfs(int s, int t)

BZOJ 1458 士兵占领 Dinic最大流

题目大意:给定一个m*n的棋盘,其中k个点有障碍,要求放置最少的士兵,使第i行有至少L[i]个,第j列有至少C[j]个 首先这种问题很明显的网络流 但是正图肯定是跑不了 限制条件是至少而且要求放置的也是最少 很难解决 反向考虑 将棋盘上先放满士兵 此时若不能满足条件则无解 然后求最多能撤掉多少个士兵 其中第i行最多撤去templ[i]-l[i]个士兵 templ[i]表示第i行当前放置的士兵个数 尼玛我的网络流是多久不写了--居然没连反向弧就跑样例--最逗的是数组开小一倍不报RE报WA-- #i

POJ--3308--Paratroopers【Dinic】二分图顶点覆盖+网络最大流

链接:http://poj.org/problem?id=3308 题意:未来世界火星人要入侵地球,他们要派一些伞兵来摧毁地球的兵工厂,兵工厂可以视为一个m*n的矩阵,现在知道了他们每个伞兵的降落位置.为了粉碎火星人的阴谋,我们需要在某行或某列来架一个机关枪来消灭一整行或一整列的火星人,但是在这需要一定的花费,告诉每行及每列架机关枪的花费,总花费是每行及每列的花费相乘.求使得火星人全部被消灭的最小花费. 思路:需要消灭所有敌人,是二分图最小点权覆盖问题,要覆盖所有的边并使花费最小,即求最小割,根