zoukankan      html  css  js  c++  java
  • BZOJ3996 TJOI2015线性代数

    先把矩阵式子化简

    原式=i=1nj=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])这样建图后我们删去的那个最小割意义就是花费最少的使得整个图不连通的量

    如果删在左边就意味着这件物品我们不要了,如果删去右边的话就说明这件物品我们要付钱。

    By:大奕哥

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=1000005,inf=1e9;
     4 int head[N],cnt=-1,n,b[505][505],c[505];
     5 struct node{
     6     int to,nex,w;
     7 }e[4000005];
     8 void add(int x,int y,int w)
     9 {
    10     e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;e[cnt].w=w;
    11     e[++cnt].to=x;e[cnt].nex=head[y];head[y]=cnt;e[cnt].w=0;
    12 }
    13 int d[N],v[N],s,t;
    14 queue<int>q;
    15 bool bfs()
    16 {
    17     memset(v,0,sizeof(v));
    18     memset(d,-1,sizeof(d));
    19     d[s]=0;q.push(s);
    20     while(!q.empty())
    21     {
    22         int x=q.front();q.pop();v[x]=1;
    23         for(int i=head[x];i!=-1;i=e[i].nex)
    24         {
    25             int y=e[i].to;
    26             if(d[y]!=-1||!e[i].w)continue;
    27             d[y]=d[x]+1;
    28             if(!v[y]){
    29                 q.push(y);v[y]=1;
    30             }
    31         }
    32     }
    33     return d[t]!=-1;
    34 }
    35 int dfs(int x,int w,int yy)
    36 {
    37     if(!w||x==yy)return w;
    38     int s=0;
    39     for(int i=head[x];i!=-1;i=e[i].nex)
    40     {
    41         int y=e[i].to;
    42         if(d[y]!=d[x]+1||!e[i].w)continue;
    43         int flow=dfs(y,min(e[i].w,w-s),yy);
    44         if(!flow)d[y]=-1;
    45         e[i].w-=flow;e[i^1].w+=flow;s+=flow;
    46         if(s==w)return s;
    47     }
    48     return s;
    49 }
    50 int main()
    51 {
    52     scanf("%d",&n);int sum=0,num=0;
    53     memset(head,-1,sizeof(head));
    54     for(int i=1;i<=n;++i)
    55     for(int j=1;j<=n;++j)
    56     {
    57         scanf("%d",&b[i][j]);
    58     }
    59     t=n*n+n+10;
    60     for(int i=1;i<=n;++i)
    61     scanf("%d",&c[i]),add(i+n*n,t,c[i]);
    62     for(int i=1;i<=n;++i)
    63     for(int j=1;j<=n;++j)
    64     {
    65         sum+=b[i][j];
    66         add(s,++num,b[i][j]);
    67         add(num,i+n*n,inf);
    68         add(num,j+n*n,inf);
    69     }
    70     while(bfs()){
    71         sum-=dfs(s,1e9,t);
    72     }
    73     printf("%d
    ",sum);
    74     return 0;
    75 }
  • 相关阅读:
    C#基础学习(二)
    C#基础学习(一)
    使用finalshll连接linux
    如何在显示表控件的时候隐藏某些列
    SMARTFORMS文本编辑器设置为SAP系统默认的
    python教学 目录
    [Unity官方文档翻译]ScrollRect
    <转载>解决div里面img的缝隙问题
    简单插入类排序
    利用border和伪类画出三角形 ps:好久没写博客了。。。
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8442918.html
Copyright © 2011-2022 走看看