bzoj3996

把这个式子弄清楚就知道这是最小割了

相当于,选某个点i有收入ai,i,会损失ci,

如果i,j都被选则有额外收入ai,j+aj,i

明显,对每个点i,连(s,i,∑ai,j) (i,t,ci)

对每对i,j连边(i,j,ai,j),没了

  1 const inf=100000007;
  2 type node=record
  3        po,next,flow:longint;
  4      end;
  5
  6 var e:array[0..2000010] of node;
  7     p,numh,h,cur,pre,d:array[0..510] of longint;
  8     t,len,ans,i,j,n,m,x,s:longint;
  9
 10 procedure add(x,y,f:longint);
 11   begin
 12     inc(len);
 13     e[len].po:=y;
 14     e[len].flow:=f;
 15     e[len].next:=p[x];
 16     p[x]:=len;
 17   end;
 18
 19 procedure build(x,y,f:longint);
 20   begin
 21     add(x,y,f);
 22     add(y,x,0);
 23   end;
 24
 25 function min(a,b:longint):longint;
 26   begin
 27     if a>b then exit(b) else exit(a);
 28   end;
 29
 30 function sap:longint;
 31   var u,i,j,tmp,neck,q:longint;
 32   begin
 33     numh[0]:=t+1;
 34     for i:=0 to t do
 35       cur[i]:=p[i];
 36     u:=0; sap:=0; neck:=inf;
 37     while h[0]<t+1 do
 38     begin
 39       d[u]:=neck;
 40       i:=cur[u];
 41       while i<>-1 do
 42       begin
 43         j:=e[i].po;
 44         if (e[i].flow>0) and (h[u]=h[j]+1) then
 45         begin
 46           neck:=min(neck,e[i].flow);
 47           pre[j]:=u;
 48           cur[u]:=i;
 49           u:=j;
 50           if u=t then
 51           begin
 52             sap:=sap+neck;
 53             while u<>0 do
 54             begin
 55               u:=pre[u];
 56               j:=cur[u];
 57               dec(e[j].flow,neck);
 58               inc(e[j xor 1].flow,neck);
 59             end;
 60             neck:=inf;
 61           end;
 62           break;
 63         end;
 64         i:=e[i].next;
 65       end;
 66       if i=-1 then
 67       begin
 68         dec(numh[h[u]]);
 69         if numh[h[u]]=0 then break;
 70         q:=-1;
 71         tmp:=t;
 72         i:=p[u];
 73         while i<>-1 do
 74         begin
 75           j:=e[i].po;
 76           if e[i].flow>0 then
 77             if tmp>h[j] then
 78             begin
 79               q:=i;
 80               tmp:=h[j];
 81             end;
 82           i:=e[i].next;
 83         end;
 84         h[u]:=tmp+1;
 85         inc(numh[h[u]]);
 86         cur[u]:=q;
 87         if u<>0 then
 88         begin
 89           u:=pre[u];
 90           neck:=d[u];
 91         end;
 92       end;
 93     end;
 94   end;
 95
 96 begin
 97   len:=-1;
 98   fillchar(p,sizeof(p),255);
 99   readln(n);
100   t:=n+1;
101   for i:=1 to n do
102   begin
103     s:=0;
104     for j:=1 to n do
105     begin
106       read(x);
107       s:=s+x;
108       build(i,j,x);
109     end;
110     build(0,i,s);
111     ans:=ans+s;
112   end;
113   for i:=1 to n do
114   begin
115     read(x);
116     build(i,t,x);
117   end;
118   writeln(ans-sap);
119 end.

时间: 2024-10-18 06:26:18

bzoj3996的相关文章

[TJOI2014] [Bzoj3996] 线性代数 [网络流,最小割]

由原式,可以推出D=Σ(i=1,n,Σ(j=1,n,A[i]*A[j]*B[i][j]))-Σ(i=1,n,A[i]*C[i]),故建图方法如下:由源点像第一层n*n个点连边,边权为B[i][j],由第一层像第二层连边,边权正无穷,由第二层向汇点连边,边权C[i].最终答案为Σ(B)-MAXFLOW. 推导过程: (A * B - C) * AT (1*n)        (n*n)       (1*n)        (n*1) =A*B    *     AT   -   C * AT (

BZOJ3996[TJOI2015]线性代数

Description 给出一个N*N的矩阵B和一个1*N的矩阵C.求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大.其中A^T为A的转置.输出D Input 第一行输入一个整数N,接下来N行输入B矩阵,第i行第J个数字代表Bij. 接下来一行输入N个整数,代表矩阵C.矩阵B和矩阵C中每个数字都是不超过1000的非负整数. Output 输出最大的D Sample Input 3 1 2 1 3 1 0 1 2 3 2 3 7 Sample Output 2 HINT 1<=N<

【BZOJ3996】【TJOI2015】线性代数 最小割

链接: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/45200381"); } 题解: 题意部分注释:最终的矩阵 D 长宽都1,所以其实要求的是一个数 首先 (A×B?C)×AT=A×B×AT?C×AT 然后发现 左边式子 Ai 和 ATj 都选的时候才会得到 Bi,j 的价值 如果 A

【bzoj3996】[TJOI2015]线性代数 最大权闭合图

题目描述 给出一个N*N的矩阵B和一个1*N的矩阵C.求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大.其中A^T为A的转置.输出D 输入 第一行输入一个整数N,接下来N行输入B矩阵,第i行第J个数字代表Bij. 接下来一行输入N个整数,代表矩阵C.矩阵B和矩阵C中每个数字都是不超过1000的非负整数. 输出 输出最大的D 样例输入 3 1 2 1 3 1 0 1 2 3 2 3 7 样例输出 2 题解 网络流最大权闭合图 (推导过程什么的不重要,只要注意一下矩阵乘法不满足结合律

BZOJ3996 线性代数

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3996 转化题目给的条件 $$D = \sum_{i=1}^n \sum_{j=1}^n{A(i)A(j)B(i,j)} - \sum_{i=1}^n C(i)A(i)$$ 网络流可解,如果要得到 $B(i,j)$ 的话必须选$i$物品和$j$物品然后,选择每一个物品都有其代价. 最大权闭合子图. 再流网络中割掉一条边就是舍弃一个$B(i,j)$ 所以最小割即可. #include <cstd

BZOJ3996 TJOI2015线性代数

先把矩阵式子化简 原式=∑i=1n∑j=1nA[i]∗B[i][j]∗A[j]−∑i=1nA[i]∗C[i] 因此我们发现问题转化为选取一个点所获收益是B[i][j],代价是C[i][j] 这是一个最小割问题. 先把答案记做所有b的和. 将边按照s——>p[i][j](b[i][j])  p[i][j]——>i p[i][j]——>j i——>t(c[i])这样建图后我们删去的那个最小割意义就是花费最少的使得整个图不连通的量 如果删在左边就意味着这件物品我们不要了,如果删去右边的话

网络流复习计划

既然是复习网络流,那就不会去做水题了吧233 A.BZOJ3996 TJOI2015线性代数 看到题就被吓坏了2333.线性代数根本没看完好吗? 然后... MD转个模型就是网络流了 “题目大意:给定一个n∗n的矩阵B和一个1∗n的行向量C,求一个1∗n的01矩阵A,使(A×B−C)×AT最大 (A×B−C)×AT=A×B×AT−C×AT 我们可以考虑有n个物品,每个物品选不选对应A中每个位置是1还是0 那么行向量C可以看做每个物品的代价 而矩阵B可以看做同时选择某两个物品时的收益 那么这个模型

[转载]hzwer的bzoj题单

counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ1202 BZOJ1051 BZOJ1001 BZOJ1588 BZOJ1208 BZOJ1491 BZOJ1084 BZOJ1295 BZOJ3109 BZOJ1085 BZOJ1041 BZOJ1087 BZOJ3038 BZOJ1821 BZOJ1076 BZOJ2321 BZOJ1934 BZOJ

网络流暂结(还差很多额)

bzoj1711: [Usaco2007 Open]Dining吃饭 最大流bzoj3993: [SDOI2015]星际战争 二分+最大流bzoj1797: [Ahoi2009]Mincut 最小割 最小割定理bzoj4873: [Shoi2017]寿司餐厅 最大权闭合子图bzoj1565: [NOI2009]植物大战僵尸 最大权闭合子图bzoj1449: [JSOI2009]球队收益 最小费用最大流(拆方)bzoj2502: 清理雪道 上下界最小流bzoj3130: [Sdoi2013]费用流