zoukankan      html  css  js  c++  java
  • POJ 1273

    POJ 1273 (吧?)

    题目大意:就是混蛋网络流,不能再裸了。

    解:请看文件夹内的关于网络流的理解。

    by me of 2012.2.9
    被网上的资料虐得一塌糊涂,有的甚至还是错的,看了三天终于切出来一条裸题了。
    对于网络流,增广流的的不断贪心已经理解,但是在看标号法ford-fulkerson的时候,对于站在u点,对于点i,若边f[i, u]存在则视为逆向弧并处理这个不甚理解。
    在整理自己理解的思路的时候,需要引入dinic的思想,不断通流导致全部通往sink汇点的路堵塞,算法结束,这里dinic每找到一条路得时候,在c[i, j] + flow的同时会连上一条边 c[j, i] - flow,这个是为了让流到这个点的流量给予反悔的机会,就是我先流到你了,随后发现你可以由其他流供应,我则不必再继续供应此点了。

    对于图
    2 1
    1 -> 2 -> 3
    1| | 2 | 1
    V V V
    4 -> 5 -> 6
    1 2

    可以发现,如果不连回去的边,若因图顺序的特殊性,我们先增广了 1, 2, 5, 6,则会发现没有路走了,最大流=2,但显然答案是3

    所以关于dinic的性质总结完毕,关于ford-fulkerson,对于负边的检查我们也可以用这个图来理解,
    在增广了1, 2, 5, 6, 后,我们走 1, 4, 5, 2, 3, 6,完成对此图的增广,对于5到6的跳跃,可以理解为,点5已经有流,所以2->5算逆向弧,我们看看能不能返还流给点2,然后看看2能不能给其他路这些多余的流,自然,我们要保证退还的等于从4给予过来的因此flow = min(l[i], fij)
    对于
    : 正向弧 : l[j] = min(l[i], cij - fij)
    逆向弧 : l[j] = min(l[i], fij)
    我们也能理解了吧?
    yoshi,去看dinic

    View Code
      1 const
    2 maxn=211;
    3 maxm=211;
    4 var
    5 f, g: array[1..maxn, 1..maxn]of longint;
    6 q, last, now: array[1..maxn]of longint;
    7 visit: array[1..maxn]of boolean;
    8 head, tail, flow, s, t, ans, n, m: longint;
    9 procedure init;
    10 var
    11 x, y, z, i, j: longint;
    12 begin
    13 fillchar(f, sizeof(f), 0);
    14 fillchar(g, sizeof(g), 0);
    15 ans := 0;
    16 readln(m, n);
    17 for i := 1 to m do
    18 begin
    19 readln(x, y, z);
    20 g[x, y] := g[x, y] + z;
    21 end;
    22 end;
    23
    24 function check: longint;
    25 var
    26 i: longint;
    27 begin
    28 for i := 1 to n do
    29 if (last[i]<>0)and(not visit[i]) then exit(i);
    30 exit(0);
    31 end;
    32
    33 function ford: boolean;
    34 var
    35 u, i, j, k, x: longint;
    36 begin
    37 ford := true;
    38 fillchar(last, sizeof(last), 0);
    39 fillchar(visit, sizeof(visit), 0);
    40 last[s] := s;
    41 head := 0;
    42 tail := 1;
    43 repeat
    44 u := check;
    45 if u=0 then exit(true);
    46 for i := 1 to n do
    47 if (last[i]=0)and((g[u, i]<>0)or(g[i, u]>0)) then
    48 begin
    49 if g[u, i]>f[u, i] then last[i] := u;
    50 if f[i, u]>0 then last[i] := -u;
    51 end;
    52 visit[u] := true;
    53 until last[t]<>0;
    54 i := t; flow := maxlongint;
    55 repeat
    56 j := i;
    57 i := abs(last[i]);
    58 if last[j]<0 then x := f[j, i];
    59 if last[j]>0 then x := g[i, j] - f[i, j];
    60 if flow > x then flow := x;
    61 until i = 1;
    62 exit(false);
    63 end;
    64
    65 procedure fulkerson(flow: longint);
    66 var
    67 i, j: longint;
    68 begin
    69 i := t;
    70 repeat
    71 j := i; i := abs(last[i]);
    72 if last[j]<0 then f[j, i] := f[j, i] - flow;
    73 if last[j]>0 then f[i, j] := f[i, j] + flow;
    74 until i=s;
    75 end;
    76
    77 procedure main;
    78 var
    79 flag : boolean;
    80 begin
    81 s := 1;
    82 t := n;
    83 flow := 0;
    84 repeat
    85 flag := ford;
    86 if flag then exit
    87 else fulkerson(flow);
    88 until false;
    89 end;
    90
    91 procedure print;
    92 var
    93 i: longint;
    94 begin
    95 for i := 2 to n do
    96 if f[1, i]<>0 then ans := ans + f[1, i];
    97 writeln(ans);
    98 end;
    99
    100 begin
    101 assign(input,'ditch.in'); reset(input);
    102 assign(output,'ditch.out'); rewrite(output);
    103 while not eof do
    104 begin
    105 init;
    106 main;
    107 print;
    108 end;
    109 close(input);
    110 end.



  • 相关阅读:
    第四次实验报告
    第三次实验报告
    第五章 循环结构课后反思
    第二次实验报告
    5-508寝室第六小组课后习题作业
    第一次实验报告
    第九章 构造数据类型实验
    第八章 指针实验
    第七章 数组实验
    第六章 函数和宏定义实验(2)
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/2435165.html
Copyright © 2011-2022 走看看