zoukankan      html  css  js  c++  java
  • 【Codevs1227】方格取数2(费用流)

    题意:给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)

    现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,

    这样一共走K次,现在要求K次所达到的方格的数的和最大。

    n<=50,k<=10

    思路:费用流

    将每个点裂成一个出点和一个入点(i,j,1..2),这个思路与最大流类似

    (i,j,1)->(i,j,2) 连两条边:

    容量为1,费用为a[i,j]

    容量为K,费用为0

    (i,j,2)->(i+1,j,1)连容量为K,费用为0的边 (i,j+1)类似

    (n,n,2)->T 连流量为K,费用为0的边限制流量

    跑最大费用最大流就行了,其实就是SPFA的三角不等式改个方向

      1 var fan:array[1..200000]of longint;
      2     q:array[0..20000]of longint;
      3     head,vet,next,len1,len2:array[1..20000]of longint;
      4     pre:array[1..20000,1..2]of longint;
      5     inq:array[1..20000]of boolean;
      6     dis:array[1..20000]of longint;
      7     a:array[1..50,1..50]of longint;
      8     num:array[1..50,1..50,1..2]of longint;
      9     n,m,k1,i,j,k,tot,s,source,src:longint;
     10     ans:int64;
     11 
     12 function min(x,y:longint):longint;
     13 begin
     14  if x<y then exit(x);
     15  exit(y);
     16 end;
     17 
     18 procedure add(a,b,c,d:longint);
     19 begin
     20  inc(tot);
     21  next[tot]:=head[a];
     22  vet[tot]:=b;
     23  len1[tot]:=c;
     24  len2[tot]:=d;
     25  head[a]:=tot;
     26 
     27  inc(tot);
     28  next[tot]:=head[b];
     29  vet[tot]:=a;
     30  len1[tot]:=0;
     31  len2[tot]:=-d;
     32  head[b]:=tot;
     33 end;
     34 
     35 function spfa:boolean;
     36 var u,t,w,i,e,v:longint;
     37 begin
     38  for i:=1 to s do
     39  begin
     40   dis[i]:=-maxlongint;
     41   inq[i]:=false;
     42  end;
     43  t:=0; w:=1; q[1]:=source; inq[source]:=true; dis[source]:=0;
     44  while t<w do
     45  begin
     46   inc(t); u:=q[t mod (s+5)];
     47   inq[u]:=false;
     48   e:=head[u];
     49   while e<>0 do
     50   begin
     51    v:=vet[e];
     52    if (len1[e]>0)and(dis[u]+len2[e]>dis[v]) then
     53    begin
     54     pre[v,1]:=u; pre[v,2]:=e;
     55     dis[v]:=dis[u]+len2[e];
     56     if not inq[v] then
     57     begin
     58      inc(w); q[w mod (s+5)]:=v;
     59      inq[v]:=true;
     60     end;
     61    end;
     62    e:=next[e];
     63   end;
     64  end;
     65  if dis[src]=-maxlongint then exit(false)
     66   else exit(true);
     67 end;
     68 
     69 procedure mcf;
     70 var k,e:longint;
     71     t:int64;
     72 begin
     73  k:=src; t:=maxlongint;
     74  while k<>source do
     75  begin
     76   e:=pre[k,2]; k:=pre[k,1];
     77   t:=min(t,len1[e]);
     78  end;
     79  k:=src;
     80  while k<>source do
     81  begin
     82   e:=pre[k,2];
     83   len1[e]:=len1[e]-t;
     84   len1[fan[e]]:=len1[fan[e]]+t;
     85   ans:=ans+t*len2[e];
     86   k:=pre[k,1];
     87  end;
     88 end;
     89 
     90 begin
     91  assign(input,'codevs1227.in'); reset(input);
     92  assign(output,'codevs1227.out'); rewrite(output);
     93  readln(n,k1);
     94  for i:=1 to 200000 do
     95   if i mod 2=1 then fan[i]:=i+1
     96    else fan[i]:=i-1;
     97  for i:=1 to n do
     98   for j:=1 to n do read(a[i,j]);
     99  for i:=1 to n do
    100   for j:=1 to n do
    101    for k:=1 to 2 do
    102    begin
    103     inc(s); num[i,j,k]:=s;
    104    end;
    105  for i:=1 to n do
    106   for j:=1 to n do
    107   begin
    108    add(num[i,j,1],num[i,j,2],1,a[i,j]);
    109    add(num[i,j,1],num[i,j,2],k1,0);
    110    if j+1<=n then add(num[i,j,2],num[i,j+1,1],k1,0);
    111    if i+1<=n then add(num[i,j,2],num[i+1,j,1],k1,0);
    112   end;
    113  source:=1; src:=s+1; inc(s);
    114  add(num[n,n,2],src,k1,0);
    115  while spfa do mcf;
    116  writeln(ans);
    117  close(input);
    118  close(output);
    119 end.
  • 相关阅读:
    javascript的语法作用域你真的懂了吗
    网页的三种布局(固定宽度式,流体式,弹性式)
    css3系列之animation
    跟我学习css3之transition
    函数调用你知道几种方法
    javascript的那些事儿你都懂了吗
    css3的那些高级选择器二
    [转]影响Cache的几个HTTP头信息
    CSS属性合写
    defer 与 async
  • 原文地址:https://www.cnblogs.com/myx12345/p/6195302.html
Copyright © 2011-2022 走看看