• POJ 3422


    POJ 3422

    题目大意:原题的加强版,k取方格数。

    解:dp,dp+降维,因为这里k可以到10,用最大费用流做。先拆点,一个点变成两个点,点中间有两条边,一条费用为该方格数,流量为1,(其负边的费用是负,一开始没想到wa了好久),另一条边费用为0而流量为无限。每次找一条去到汇点的最大费用路。然后找出最小流,用pre记录前缀,从汇点回溯到原点,并更新每条边的流量。注意原点到1,1的流量为maxlongint,n,n到汇点的流量为k。这里也是wa的地方。

    View Code
      1 //poj 3422
    2 const
    3 maxn=(52 * 52) << 1;
    4 maxm=(maxn << 2)+ 10086;
    5 bilibili=maxlongint >> 1;
    6 type
    7 data=record
    8 dest, next, cost, w, op: longint;
    9 end;
    10 var
    11 edge: array[1..maxm]of data;
    12 q, vect, dist, from, from_edge: array[1..maxn]of longint;
    13 visit: array[1..maxn]of boolean;
    14 flow, ans, tot, sink, source, n, k: longint;
    15 procedure add(x, y, z, fy: longint);
    16 begin
    17 inc(tot);
    18 with edge[tot] do begin
    19 dest := y;
    20 cost := z;
    21 w := fy;
    22 next := vect[x];
    23 vect[x] := tot;
    24 op := tot +1;
    25 end;
    26 inc(tot);
    27 with edge[tot] do begin
    28 dest := x;
    29 cost := 0;
    30 w := -fy;
    31 next := vect[y];
    32 vect[y] := tot;
    33 op := tot -1;
    34 end;
    35 end;
    36
    37 procedure init;
    38 var
    39 i, j, x, tmp, y, z: longint;
    40 begin
    41 tot := 0; ans := 0;
    42 fillchar(vect, sizeof(vect), 0);
    43 readln(n, k);
    44 source := (n*n)<<1 +1; sink := source +1;
    45 for i := 1 to n do begin
    46 for j := 1 to n do begin
    47 read(tmp);
    48 x := (i-1)*n + j;
    49 y := x << 1;
    50 x := y-1;
    51 add(x, y, 1, tmp);
    52 add(x, y, bilibili, 0);
    53 x := y;
    54 y := ((i-1)*n+j+1)<<1 -1;
    55 z := (i*n+j)<<1 -1;
    56 if j<n then add(x, y, bilibili, 0);
    57 if i<n then add(x, z, bilibili, 0);
    58 end;
    59 readln;
    60 end;
    61 add(source, 1, bilibili, 0);
    62 add(n*n*2, sink, k, 0);
    63 end;
    64
    65 function spfa: boolean;
    66 var
    67 head, tail, i, u: longint;
    68 begin
    69 for i := 1 to sink do dist[i] := -bilibili;
    70 fillchar(visit, sizeof(visit), 0);
    71 head := 0; tail := 1;
    72 q[tail] := source; dist[source] := 0;
    73 visit[source] := true;
    74 repeat
    75 inc(head); if head=maxn+1 then head := 1;
    76 u := q[head];
    77 visit[u] := false;
    78 i := vect[u];
    79 while i<>0 do
    80 with edge[i] do begin
    81 if (cost>0)and(dist[u] + w > dist[dest]) then begin
    82 dist[dest] := dist[u] +w;
    83 from[dest] := u;
    84 from_edge[dest] := i;
    85 if not visit[dest] then begin
    86 inc(tail); if tail=maxn + 1 then tail := 1;
    87 visit[dest] := true;
    88 q[tail] := dest;
    89 end;
    90 end;
    91 i := next;
    92 end;
    93 until head=tail;
    94 exit(dist[sink]<>-bilibili);
    95 end;
    96
    97 procedure main;
    98 var
    99 i, u: longint;
    100 begin
    101 while spfa do begin
    102 u := sink;
    103 flow := bilibili;
    104 while u<>source do begin
    105 if edge[from_edge[u]].cost < flow then flow := edge[from_edge[u]].cost;
    106 u := from[u];
    107 end;
    108 u := sink;
    109 while u<>source do begin
    110 i := from_edge[u];
    111 with edge[i] do begin
    112 dec(cost);
    113 inc(edge[op].cost);
    114 inc(ans, w*flow);
    115 end;
    116 u := from[u];
    117 end;
    118 end;
    119 end;
    120
    121 procedure print;
    122 begin
    123 writeln(ans);
    124 end;
    125
    126 begin
    127 assign(input,'aaa.in'); reset(input);
    128 init;
    129 main;
    130 print;
    131 end.



  • 相关阅读:
    DAY 179 在Flask中使用MongoDB:Flask-MongoEngine
    DAY 178 oracle基础
    DAY 177 mongoengine
    DAY 176 redis教程
    存储器
    cpu
    java 类文件类型
    线程池
    CopyOnWrite容器
    ConcurrentHashMap
  • 原文地址:https://www.cnblogs.com/wmzisfoolish/p/2435180.html
Copyright © 2020-2023  润新知