• 最大流 最小费用流模板


     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 using namespace std;
     6 const int INF = 0x3f3f3f3f;
     7 const int N = 10005;
     8 const int M = 100005;
     9 struct type{
    10     int u, v, w, next;
    11 }edge[M << 1];
    12 int head[N], cnt;
    13 int dep[N], cur[N];
    14 int n, m, s, t, d;
    15 void add(int x, int y, int z){
    16     edge[cnt].u = x;
    17     edge[cnt].v = y;
    18     edge[cnt].w = z;
    19     edge[cnt].next = head[x];
    20     head[x] = cnt;
    21     cnt++;
    22 }
    23 bool bfs(){
    24     int fro = 0;
    25     queue<int> q;
    26     q.push(s);
    27     for(int i = 1; i <= n; i++) dep[i] = 0;
    28     dep[s] = 1;//important!!!!!
    29     while(!q.empty()){
    30         fro = q.front(); q.pop();
    31         for(int i = head[fro]; i != -1; i = edge[i].next){
    32             int vv = edge[i].v;
    33             if(!dep[vv] && edge[i].w > 0){
    34                 dep[vv] = dep[fro] + 1;
    35                 q.push(vv);
    36             }
    37         }
    38     }
    39     return dep[t] ? 1 : 0;
    40 }
    41 int dfs(int x, int rest){
    42     if(x == t || !rest) return rest;
    43     for(int& i = cur[x]; i != -1; i = edge[i].next){//当前弧优化 
    44         int vv = edge[i].v, ww = edge[i].w;
    45         if(dep[vv] != dep[x] + 1) continue;
    46         d = dfs(vv, min(rest, ww));
    47         if(d > 0){
    48             edge[i].w -= d;
    49             edge[i ^ 1].w += d;
    50             return d;
    51         }
    52     }
    53     return 0;
    54 }
    55 int dinic(){
    56     int ans = 0;
    57     while(bfs()){
    58         for(int i = 1; i <= n; i++) cur[i] = head[i];//当前弧优化
    59         if(d = dfs(s, INF)){
    60             ans += d;
    61         }
    62     }
    63     return ans;
    64 }
    65 int main() {
    66     int x, y, z;
    67     scanf("%d%d%d%d", &n, &m, &s, &t);
    68     for(int i = 1; i <= n; i++) head[i] = -1;
    69     for(int i = 1; i <= m; i++){
    70         scanf("%d%d%d", &x, &y, &z);
    71         add(x, y, z);
    72         add(y, x, 0);
    73     }
    74     printf("%d", dinic());
    75     return 0;
    76 }
    最大流dinic
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 using namespace std;
     6 const int INF = 0x3f3f3f3f;
     7 const int N = 5005;
     8 const int M = 50005;
     9 struct type{
    10     int u, v, w, f, next;
    11 }edge[M << 1];
    12 struct type2{
    13     int f, cur, incf;
    14     bool vis;
    15 }ser[N];
    16 int head[N], cnt;
    17 int n, m, s, t;
    18 int max_flow, min_cost;
    19 void add(int x, int y, int z, int zz){
    20     edge[cnt].u = x;
    21     edge[cnt].v = y;
    22     edge[cnt].w = z;
    23     edge[cnt].f = zz;
    24     edge[cnt].next = head[x];
    25     head[x] = cnt;
    26     cnt++;
    27 }
    28 bool spfa(){
    29     for(int i = 1; i <= n; i++){
    30         ser[i].vis = 0;
    31         ser[i].f = INF;
    32     }
    33     ser[s].f = 0;
    34     ser[s].incf = INF;  
    35     int fro;
    36     queue<int> q;
    37     q.push(s);
    38     while(!q.empty()){
    39         fro = q.front(); q.pop(); ser[fro].vis = 0;
    40         for(int i = head[fro]; i != -1; i = edge[i].next){
    41             int vv = edge[i].v, ww = edge[i].w, ff = edge[i].f;
    42             if(ww > 0 && ser[fro].f + ff < ser[vv].f){
    43                 ser[vv].f = ser[fro].f + ff;
    44                 ser[vv].incf = min(ser[fro].incf, ww);
    45                 ser[vv].cur = i;
    46                 if(!ser[vv].vis){
    47                     ser[vv].vis = 1;
    48                     q.push(vv);
    49                 }
    50             }
    51         }
    52     }
    53     return ser[t].f == INF ? 0 : 1;
    54 }
    55 void update(){
    56     int i = t, j;
    57     while(i != s){
    58         j = ser[i].cur;
    59         edge[j].w -= ser[t].incf;
    60         edge[j ^ 1].w += ser[t].incf;
    61         i = edge[j].u;
    62     }
    63     max_flow += ser[t].incf;
    64     min_cost += ser[t].f * ser[t].incf;
    65 }
    66 void EK(){
    67     while(spfa()){
    68         update();
    69     }
    70 }
    71 int main() {
    72     //freopen("testdata.in", "r", stdin);
    73     //freopen("testdata.out", "w", stdout);
    74     int x, y, z, zz;
    75     scanf("%d%d%d%d", &n, &m, &s, &t);
    76     for(int i = 1; i <= n; i++) head[i] = -1;
    77     for(int i = 1; i <= m; i++){
    78         scanf("%d%d%d%d", &x, &y, &z, &zz);
    79         add(x, y, z, zz);
    80         add(y, x, 0, -zz);
    81     }
    82     EK();
    83     printf("%d %d
    ", max_flow, min_cost);
    84     return 0;
    85 }
    最小费用最大流EK
  • 相关阅读:
    ExceptionExtensions
    implicit operator
    javascript Demo
    KO Demo
    Model Binding
    Await Async Task
    STL查找序列中处于某一大小范围内的元素个数
    2017头条笔试题:二维点集中找出右上角没有点的点并按x坐标从小到大打印坐标
    VS2017新建windows控制台程序打印中文乱码问题
    【详解】Linux的文件描述符fd与文件指针FILE*互相转换
  • 原文地址:https://www.cnblogs.com/hjmmm/p/9261480.html
Copyright © 2020-2023  润新知