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<=500

题解:

这题包装得可真好啊……

D=A*B*A^T-C*A^T

假如A的第i项为1,则D会减去C[1,i]。

假如A的第i项、第j项都为1,则D会加上B[i,j]。

这样,题目就变成了类似于BZOJ1497[NOI2006]最大获利的模型:n个物品,取某个物品会有代价,若同时取某两个物品则会有收益。

题目变成了最大权闭合子图问题,用DINIC网络流求最小割求解。

代码:

const
  inf=100000000;
type
  rec=record
    s,e,w,flow,next:longint;
  end;
var
  b,bb,d,q:array[0..2002002] of longint;
  a:array[-1..2002000] of rec;
  v:array[0..2002000] of boolean;
  n,m,i,j,k,l,st,ed,ww,top,tar,ans,x:longint;
function min(aa,bb:longint):longint;
begin
  if aa<bb then exit(aa);exit(bb);
end;
procedure add(st,ed,ww:longint);
begin
  inc(top);
  a[top].s:=st;
  a[top].e:=ed;
  a[top].w:=ww;
  a[top].next:=b[st];
  b[st]:=top;
end;
function bfs:boolean;
var head,tail,x,u:longint;
  y:rec;
begin
  fillchar(v,sizeof(v),false);
  tail:=1; head:=0; d[st]:=1;
  v[st]:=true; q[1]:=st;
  while head<tail do
  begin
    inc(head); x:=q[head];
    u:=b[x];
    while u>0 do
    begin
      y:=a[u];
      if(not v[y.e])and(y.flow<y.w)then
      begin
        v[y.e]:=true;
        d[y.e]:=d[x]+1;
        inc(tail); q[tail]:=y.e;
      end;
      u:=y.next;
    end;
  end;
  exit(v[tar]);
end;
function addflow(p,maxflow:longint):longint;
var
  o:longint;
  y:rec;
begin
  if(p=tar)or(maxflow=0)then exit(maxflow);
  addflow:=0;
  while bb[p]>0 do
  begin
    y:=a[bb[p]];
    if(d[y.e]=d[p]+1)and(y.flow<y.w)then
    begin
      o:=addflow(y.e,min(maxflow,y.w-y.flow));
      if o>0 then
      begin
        inc(a[bb[p]].flow,o);
        dec(a[bb[p] xor 1].flow,o);
        dec(maxflow,o);
        inc(addflow,o);
        if maxflow=0 then break;
      end;
    end;
    bb[p]:=y.next;
  end;
end;
function network:longint;
begin
  network:=0;
  while bfs do
  begin
    for i:=st to tar do bb[i]:=b[i];
    inc(network,addflow(st,inf));
  end;
end;
begin
  readln(n); st:=0;
  top:=1; tar:=n;
  for i:=1 to n do
  for j:=1 to n do
  begin
    read(x);
    if x>0 then
    begin
      inc(tar);
      add(st,tar,x);
      add(tar,st,0);
      add(tar,i,inf);
      add(i,tar,0);
      add(tar,j,inf);
      add(j,tar,0);
      ans:=ans+x;
    end;
  end;
  inc(tar);
  for i:=1 to n do
  begin
    read(j);
    add(i,tar,j);
    add(tar,i,0);
  end;
  writeln(ans-network);
end.

时间: 2024-10-05 04:40:34

BZOJ3996[TJOI2015]线性代数的相关文章

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])这样建图后我们删去的那个最小割意义就是花费最少的使得整个图不连通的量 如果删在左边就意味着这件物品我们不要了,如果删去右边的话

【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 题解 网络流最大权闭合图 (推导过程什么的不重要,只要注意一下矩阵乘法不满足结合律

[TJOI2015]线性代数

题目链接 戳我 \(Describe\) 题目描述 为了提高智商,\(ZJY\)开始学习线性代数.她的小伙伴菠萝给她出了这样一个问题:给定一个\(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\)个数代表\(B\)接下来一行输

bzoj1497: [NOI2006]最大获利&amp;&amp;3996: [TJOI2015]线性代数

给出一个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 化简一下式子, 给出一个N*N的矩阵B和一个

BZOJ 3966 TJOI2015 线性代数 网络流

题目大意:给定一个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可以看做同时选择某两个物品时的收益 那么这个模型就被我们直接分析出来了,网络流走起~ #include <cstdio> #include <cstring> #include <iostream> #inc

BZOJ_3996_[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<

网络流复习计划

既然是复习网络流,那就不会去做水题了吧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可以看做同时选择某两个物品时的收益 那么这个模型

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

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

【BZOJ】【TJOI2015】线性代数

网络流/最小割/最大权闭合图 2333好开心,除了一开始把$500^2$算成25000……导致数组没开够RE了一发,可以算是一次AC~ 咳咳还是回归正题来说题解吧: 一拿到这道题,我就想:这是什么鬼玩意……矩阵乘法早忘了……画了半天也想不起来到底是谁乘谁,只记得有个式子:$c[i][j]=\sum a[i][k]*b[k][j]$ 好吧没关系,既然画图不行了,我们就先拿这个东西,纯代数来搞! D的表达式,里面那层我们可以写成:$\sum a[i][k]*b[k][j] - c[i][j]$ 然而