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

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

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\n",sum);
74     return 0;
75 }

原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8442918.html

时间: 2024-10-19 23:46:02

BZOJ3996 TJOI2015线性代数的相关文章

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]线性代数 最大权闭合图

题目描述 给出一个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]$ 然而