【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.
null