【BZOJ2127】happiness(最小割)

题意:高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友。

这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,

而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值。

作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大。

对于100%以内的数据,n,m<=100 所有喜悦值均为小于等于5000的非负整数

思路:同BZOJ3894

双倍经验

话说这是一个经典网络流模型

  1 var head,vet,next,len,gap,dis,fan:array[0..1100000]of longint;
  2     a,num:array[1..100,1..100,1..2]of longint;
  3     n,m,tot,i,j,sum,s,source,src,k,x,y,tmp:longint;
  4 
  5 procedure add(a,b,c:longint);
  6 begin
  7  inc(tot);
  8  next[tot]:=head[a];
  9  vet[tot]:=b;
 10  len[tot]:=c;
 11  head[a]:=tot;
 12 
 13  inc(tot);
 14  next[tot]:=head[b];
 15  vet[tot]:=a;
 16  len[tot]:=0;
 17  head[b]:=tot;
 18 end;
 19 
 20 function min(x,y:longint):longint;
 21 begin
 22  if x<y then exit(x);
 23  exit(y);
 24 end;
 25 
 26 function dfs(u,aug:longint):longint;
 27 var e,v,val,flow,t:longint;
 28 begin
 29  if u=src then exit(aug);
 30  e:=head[u]; val:=s-1; flow:=0;
 31  while e<>0 do
 32  begin
 33   v:=vet[e];
 34   if len[e]>0 then
 35   begin
 36    if dis[u]=dis[v]+1 then
 37    begin
 38     t:=dfs(v,min(len[e],aug-flow));
 39     len[e]:=len[e]-t;
 40     len[fan[e]]:=len[fan[e]]+t;
 41     flow:=flow+t;
 42     if dis[source]>=s then exit(flow);
 43     if aug=flow then break;
 44    end;
 45    val:=min(val,dis[v]);
 46   end;
 47   e:=next[e];
 48  end;
 49  if flow=0 then
 50  begin
 51   dec(gap[dis[u]]);
 52   if gap[dis[u]]=0 then dis[source]:=s;
 53   dis[u]:=val+1;
 54   inc(gap[dis[u]]);
 55  end;
 56  exit(flow);
 57 end;
 58 
 59 function maxflow:longint;
 60 var ans:longint;
 61 begin
 62  fillchar(gap,sizeof(gap),0);
 63  fillchar(dis,sizeof(dis),0);
 64  gap[0]:=s; ans:=0;
 65  while dis[source]<s do ans:=ans+dfs(source,maxlongint);
 66  exit(ans);
 67 end;
 68 
 69 begin
 70  assign(input,'bzoj2127.in'); reset(input);
 71  assign(output,'bzoj2127.out'); rewrite(output);
 72  readln(n,m);
 73  for i:=1 to 1100000 do
 74   if i and 1=1 then fan[i]:=i+1
 75    else fan[i]:=i-1;
 76  for i:=1 to 2 do
 77   for j:=1 to n do
 78    for k:=1 to m do
 79    begin
 80     read(a[j,k,i]);
 81     inc(s); num[j,k,i]:=s;
 82     sum:=sum+a[j,k,i];
 83    end;
 84  tmp:=s;
 85  s:=2*(n*m+(n-1)*m+(m-1)*n);
 86  source:=s+1; src:=s+2;
 87  s:=s+2;
 88  for i:=1 to n do
 89   for j:=1 to m do add(source,num[i,j,1],a[i,j,1]);
 90  for i:=1 to n do
 91   for j:=1 to m do add(num[i,j,2],src,a[i,j,2]);
 92  for i:=1 to n do
 93   for j:=1 to m do add(num[i,j,1],num[i,j,2],maxlongint);
 94  for i:=1 to n-1 do
 95   for j:=1 to m do
 96   begin
 97    read(x); inc(tmp); sum:=sum+x;
 98    add(source,tmp,x);
 99    add(tmp,num[i,j,1],maxlongint);
100    add(tmp,num[i+1,j,1],maxlongint);
101   end;
102  for i:=1 to n-1 do
103   for j:=1 to m do
104   begin
105    read(x); inc(tmp); sum:=sum+x;
106    add(tmp,src,x);
107    add(num[i,j,2],tmp,maxlongint);
108    add(num[i+1,j,2],tmp,maxlongint);
109   end;
110  for i:=1 to n do
111   for j:=1 to m-1 do
112   begin
113    read(x); inc(tmp); sum:=sum+x;
114    add(source,tmp,x);
115    add(tmp,num[i,j,1],maxlongint);
116    add(tmp,num[i,j+1,1],maxlongint);
117   end;
118  for i:=1 to n do
119   for j:=1 to m-1 do
120   begin
121    read(x); inc(tmp); sum:=sum+x;
122    add(tmp,src,x);
123    add(num[i,j,2],tmp,maxlongint);
124    add(num[i,j+1,2],tmp,maxlongint);
125   end;
126 
127  writeln(sum-maxflow);
128 end.
129 
130 
131 
132 
133  close(input);
134  close(output);
135 end.

 

posted on 2017-03-03 10:10  myx12345  阅读(132)  评论(0编辑  收藏  举报

导航