zoukankan      html  css  js  c++  java
  • 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网络流求最小割求解。

    代码:

      1 const
      2   inf=100000000;
      3 type
      4   rec=record
      5     s,e,w,flow,next:longint;
      6   end;
      7 var
      8   b,bb,d,q:array[0..2002002] of longint;
      9   a:array[-1..2002000] of rec;
     10   v:array[0..2002000] of boolean;
     11   n,m,i,j,k,l,st,ed,ww,top,tar,ans,x:longint;
     12 function min(aa,bb:longint):longint;
     13 begin
     14   if aa<bb then exit(aa);exit(bb);
     15 end;
     16 procedure add(st,ed,ww:longint);
     17 begin
     18   inc(top);
     19   a[top].s:=st;
     20   a[top].e:=ed;
     21   a[top].w:=ww;
     22   a[top].next:=b[st];
     23   b[st]:=top;
     24 end;
     25 function bfs:boolean;
     26 var head,tail,x,u:longint;
     27   y:rec;
     28 begin
     29   fillchar(v,sizeof(v),false);
     30   tail:=1; head:=0; d[st]:=1;
     31   v[st]:=true; q[1]:=st;
     32   while head<tail do
     33   begin
     34     inc(head); x:=q[head];
     35     u:=b[x];
     36     while u>0 do
     37     begin
     38       y:=a[u];
     39       if(not v[y.e])and(y.flow<y.w)then
     40       begin
     41         v[y.e]:=true;
     42         d[y.e]:=d[x]+1;
     43         inc(tail); q[tail]:=y.e;
     44       end;
     45       u:=y.next;
     46     end;
     47   end;
     48   exit(v[tar]);
     49 end;
     50 function addflow(p,maxflow:longint):longint;
     51 var
     52   o:longint;
     53   y:rec;
     54 begin
     55   if(p=tar)or(maxflow=0)then exit(maxflow);
     56   addflow:=0;
     57   while bb[p]>0 do
     58   begin
     59     y:=a[bb[p]];
     60     if(d[y.e]=d[p]+1)and(y.flow<y.w)then
     61     begin
     62       o:=addflow(y.e,min(maxflow,y.w-y.flow));
     63       if o>0 then
     64       begin
     65         inc(a[bb[p]].flow,o);
     66         dec(a[bb[p] xor 1].flow,o);
     67         dec(maxflow,o);
     68         inc(addflow,o);
     69         if maxflow=0 then break;
     70       end;
     71     end;
     72     bb[p]:=y.next;
     73   end;
     74 end;
     75 function network:longint;
     76 begin
     77   network:=0;
     78   while bfs do
     79   begin
     80     for i:=st to tar do bb[i]:=b[i];
     81     inc(network,addflow(st,inf));
     82   end;
     83 end;
     84 begin
     85   readln(n); st:=0;
     86   top:=1; tar:=n;
     87   for i:=1 to n do
     88   for j:=1 to n do
     89   begin
     90     read(x);
     91     if x>0 then
     92     begin
     93       inc(tar);
     94       add(st,tar,x);
     95       add(tar,st,0);
     96       add(tar,i,inf);
     97       add(i,tar,0);
     98       add(tar,j,inf);
     99       add(j,tar,0);
    100       ans:=ans+x;
    101     end;
    102   end;
    103   inc(tar);
    104   for i:=1 to n do
    105   begin
    106     read(j);
    107     add(i,tar,j);
    108     add(tar,i,0);
    109   end;
    110   writeln(ans-network);
    111 end.
    View Code
  • 相关阅读:
    转inux Shell编程入门
    转CentOS — MySQL备份 Shell 脚本
    JAVA4种线程池的使用
    http://cyber-dojo.org/
    tomcat内存大小设置
    rails的数据库查询方法
    Java 微信公众号上传永久素材的方法
    微信回复图文消息
    plsql解决64位解决办法
    Ruby中使用patch HTTP方法
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6262585.html
Copyright © 2011-2022 走看看