zoukankan      html  css  js  c++  java
  • 1565: [NOI2009]植物大战僵尸

    Description


    Input


    Output
    仅包含一个整数,表示可以获得的最大能源收入。注意,你也可以选择不进行任何攻击,这样能源收入为0。
    Sample Input
    3 2
    10 0
    20 0
    -10 0
    -5 1 0 0
    100 1 2 1
    100 0
    Sample Output
    25
    HINT

    在样例中, 植物P1,1可以攻击位置(0,0), P2, 0可以攻击位置(2,1)。
    一个方案为,首先进攻P1,1, P0,1,此时可以攻击P0,0 。共得到能源收益为(-5)+20+10 = 25。注意, 位置(2,1)被植物P2,0保护,所以无法攻击第2行中的任何植物。
    【大致数据规模】
    约20%的数据满足1 ≤ N, M ≤ 5;
    约40%的数据满足1 ≤ N, M ≤ 10;
    约100%的数据满足1 ≤ N ≤ 20,1 ≤ M ≤ 30,-10000 ≤ Score ≤ 10000 。

    详情请见胡伯涛《最小割模型在信息学竞赛中的应用》中最大权闭合图

    但是有一点不同,因为有些点不能取,所以我们首先拓扑一下,把有用的点选出来,然后再跑最小割

      1 const
      2     maxn=22;
      3     maxm=33;
      4     inf=10000000;
      5 var
      6     d,a,first,q:array[0..maxn*maxm]of longint;
      7     next,last:array[0..maxn*maxm*maxn*maxm]of longint;
      8     map:array[0..maxn*maxm,0..maxn*maxm]of longint;
      9     n,m,tot,sum,cnt:longint;
     10  
     11 function calc(i,j:longint):longint;
     12 begin
     13     exit(i*m+j+1);
     14 end;
     15  
     16 procedure insert(x,y:longint);
     17 begin
     18     inc(tot);
     19     last[tot]:=y;
     20     next[tot]:=first[x];
     21     first[x]:=tot;
     22     inc(d[y]);
     23 end;
     24  
     25 procedure init;
     26 var
     27     i,j,k,l,r,x,y:longint;
     28 begin
     29     read(n,m);
     30     for i:=0 to n-1 do
     31         for j:=0 to m-1 do
     32             begin
     33                 read(a[calc(i,j)]);
     34                 read(k);
     35                 if j>0 then insert(calc(i,j),calc(i,j-1));
     36                 for l:=1 to k do
     37                     begin
     38                         read(x,y);
     39                         insert(calc(i,j),calc(x,y));
     40                     end;
     41             end;
     42     l:=1;r:=0;
     43     for i:=0 to n -1do
     44         if d[calc(i,m-1)]=0 then
     45         begin
     46             inc(r);
     47             q[r]:=calc(i,m-1);
     48         end;
     49     while l<=r do
     50         begin
     51             if a[q[l]]>0 then inc(sum,a[q[l]]);
     52             if a[q[l]]>0 then inc(map[0,q[l]],a[q[l]]);
     53             if a[q[l]]<0 then inc(map[q[l],n*m+1],-a[q[l]]);
     54             i:=first[q[l]];
     55             while i<>0 do
     56                 begin
     57                     dec(d[last[i]]);inc(map[last[i],q[l]],inf);
     58                     if d[last[i]]=0 then
     59                     begin
     60                         inc(r);
     61                         q[r]:=last[i];
     62                     end;
     63                     i:=next[i];
     64                 end;
     65             inc(l);
     66         end;
     67     cnt:=r;
     68 end;
     69  
     70 var
     71     dis,vh,his,pre:array[0..maxn*maxm]of longint;
     72     flow:longint;
     73  
     74 procedure sap;
     75 var
     76     i,j,aug,min:longint;
     77     flag:boolean;
     78 begin
     79     vh[0]:=cnt+2;
     80     i:=0;aug:=inf;
     81     while dis[i]<n*m+2 do
     82         begin
     83             his[i]:=aug;
     84             flag:=false;
     85             for j:=0 to n*m+1 do
     86                 if (map[i,j]>0) and (dis[i]=dis[j]+1) then
     87                 begin
     88                     flag:=true;
     89                     if aug>map[i,j] then aug:=map[i,j];
     90                     pre[j]:=i;
     91                     i:=j;
     92                     if i=n*m+1 then
     93                     begin
     94                         inc(flow,aug);
     95                         while i<>0 do
     96                             begin
     97                                 inc(map[i,pre[i]],aug);
     98                                 dec(map[pre[i],i],aug);
     99                                 i:=pre[i];
    100                             end;
    101                         aug:=inf;
    102                     end;
    103                     break;
    104                 end;
    105             if flag then continue;
    106             min:=n*m+1;
    107             for j:=0 to n*m+1 do
    108                 if (map[i,j]>0) and (dis[j]<min) then min:=dis[j];
    109             dec(vh[dis[i]]);
    110             if vh[dis[i]]=0 then break;
    111             dis[i]:=min+1;
    112             inc(vh[min+1]);
    113             if i<>0 then
    114             begin
    115                 i:=pre[i];
    116                 aug:=his[i];
    117             end;
    118         end;
    119     writeln(sum-flow);
    120 end;
    121  
    122 begin
    123     init;
    124     sap;
    125 end.
    View Code
  • 相关阅读:
    To My Girlfriend (DP)
    A Simple Nim (SG打表找规律)
    A Boring Question (打表)
    A Simple Chess (Lucas组合数 + 容斥)
    World is Exploding (容斥 + 统计)
    Two (DP)
    K-wolf Number (数位DP)
    Interesting (manacher + 前缀和处理)
    How Many Triangles (极角排序 + 尺取法)
    Divide the Sequence (贪心)
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3811430.html
Copyright © 2011-2022 走看看