zoukankan      html  css  js  c++  java
  • 最大流入门 之 poj 1273

    //  [5/7/2014 Sjm]
    /*
    图论之最大流:
    Ford-Fulkerson方法 dfs 实现
    第一次接触网络流的题目,卡了好久。。。最后终于理解了代码,自己能敲出来了。。。
    教训: (体会了算法的思想 != 能写出好的代码) => 要 知行合一
     
    对代码细节理解(需要理解的关键位置):
    1)对于 void Add_edge(int from, int to, int cap) 函数:
       在构建出 s->t  的正向边后,立即构建 t->s 的反向边(容量为0)
    2)dfs 回朔时,正向边与反向边容量变化。
    */
     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <vector>
     6 #include <algorithm>
     7 using namespace std;
     8 
     9 const int MAX_M = 200, INF = 0x3f3f3f3f;
    10 struct edge { int to, cap, rev; }; 
    11 //     边   {终点, 容量, 反向边}
    12 vector<edge> G[MAX_M];  // 邻接表构图
    13 bool used[MAX_M];  // 用于 dfs 时判断点是否被访问过。
    14 
    15 // 增加一条
    16 void Add_edge(int from, int to, int cap) {
    17     edge e1 = { to, cap, G[to].size() };
    18     G[from].push_back(e1);  
    19     // 增加 from -> to 的正向边
    20     edge e2 = { from, 0, G[from].size() - 1 };  
    21     // 增加 to -> from 的反向边
    22     G[to].push_back(e2);
    23 }
    24 
    25 int Dfs(int v, int t, int f) {
    26     if (v == t) return f;
    27     used[v] = true;
    28     for (int i = 0; i < G[v].size(); i++) {
    29         edge &e = G[v][i];
    30         if (!used[e.to] && e.cap > 0) {
    31             int d = Dfs(e.to, t, min(f, e.cap));
    32             if (d > 0) {
    33                 e.cap -= d;
    34                 // 增流后,正向边容量减少 d
    35                 G[e.to][e.rev].cap += d;
    36                 // 增流后,反向边容量增加 d
    37                 return d;
    38             }
    39         }
    40     }
    41     return 0;
    42 }
    43 
    44 int Max_flow(int s, int t) {
    45     int max_flow = 0;
    46     for (;;) {
    47         memset(used, 0, sizeof(used));
    48         int f = Dfs(s, t, INF);
    49         if (!f) return max_flow;
    50         max_flow += f;
    51     }
    52 }
    53 
    54 int main()
    55 {
    56     //freopen("input.txt", "r", stdin);
    57     //freopen("output.txt", "w", stdout);
    58     int n, m;
    59     while (~scanf("%d %d", &n, &m))
    60     {
    61         for (int i = 0; i < n; i++) {
    62             int from, to, flow;
    63             scanf("%d %d %d", &from, &to, &flow);
    64             Add_edge(from - 1, to - 1, flow);
    65         }
    66         printf("%d
    ", Max_flow(0, m - 1));
    67         for (int i = 0; i < m; i++) {
    68             G[i].clear();
    69         }
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    Permission Denial: opening provider 隐藏的android:exported属性的含义
    GPL & Apache License
    JAVA把毫秒数转换成日期
    Android开发–Intent-filter属性详解
    [转]unix/linux中的dup()系统调用
    【转载】技术的正宗与野路子
    virtualbox -centos ping不通外网
    GNU Make 手册中文版
    Git源码学习
    git-gui
  • 原文地址:https://www.cnblogs.com/shijianming/p/4140852.html
Copyright © 2011-2022 走看看