题面

题面

题解

先化一波式子:

\[D = (A \cdot B - C)A^T
\]

\[= \sum_{i = 1}^{n}H_{1i}\cdot A^T_{i1}
\]

\[H_{1i} = (\sum_{j = 1}^{n}A_{1j} \cdot B_{ji}) - C_{1i}
\]

\[D = \sum_{i = 1}^{n}{((\sum_{j = 1}^{n}A_{1j} \cdot B_{ji}) - C_{1i}) A^T_{i1}}
\]

\[D = \sum_{i = 1}^{n}{((\sum_{j = 1}^{n}A_{1j} \cdot B_{ji}) - C_{1i}) A_{1i}}
\]

\[= \sum_{i = 1}^{n} \sum_{j = 1}^{n}A_j \cdot B_{ji} \cdot A_i - \sum_{i = 1}^{n}C_iA_i
\]

\[= \sum_{i = 1}^{n} \sum_{j = 1}^{n}A_i \cdot B_{ij} \cdot A_j - \sum_{i = 1}^{n}C_iA_i
\]

因此选\(i\)和\(j\)则得到\(B_{ij}\)的贡献,选\(i\)则花费\(C_i\)的代价。

因此我们有如下关系:选\((i, j)\)则必选\(i, j\).

因此建图方式如下:

  • 对于每个二元组\((i, j)\),我们连\(s --- > (i, j) : B_{ij}\)
  • 对于每个二元组\((i, j)\),我们连\((i, j) ---> i : inf , (i, j) ---> j : inf\)
  • 对于每个点\(i\),我们连\(i ---> t : C_i\)
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 550
#define ac 1000000
#define maxn 3000000
#define inf 1000000000
//#define D printf("in line %d\n", __LINE__); int n, s, t, x, addflow, ans, all;
int B[AC][AC], C[AC];
int Head[ac], date[maxn], Next[maxn], haveflow[maxn], tot = 1;
int have[ac], good[ac], c[ac], last[ac];
int q[ac], head, tail; inline int read()
{
int x = 0;char c = getchar();
while(c > '9' || c < '0') c = getchar();
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x;
} inline void upmin(int &a, int b) {if(b < a) a = b;}
inline void upmax(int &a, int b) {if(b > a) a = b;} inline void add(int f, int w, int S)
{
date[++ tot] = w, Next[tot] = Head[f], Head[f] = tot, haveflow[tot] = S;
date[++ tot] = f, Next[tot] = Head[w], Head[w] = tot, haveflow[tot] = 0;
//printf("%d --- > %d : %d\n", f, w, S);
} void bfs()
{
q[++ tail] = t, have[1] = c[t] = 1;
while(head < tail)
{
int x = q[++ head];
for(R i = Head[x]; i; i = Next[i])
{
int now = date[i];
if(!c[now] && haveflow[i ^ 1])
{
++ have[c[now] = c[x] + 1];
q[++ tail] = now;
}
}
}
memcpy(good, Head, sizeof(good));
} void aru()
{
while(x != s)
{
haveflow[last[x]] -= addflow;
haveflow[last[x] ^ 1] += addflow;
x = date[last[x] ^ 1];
}
ans -= addflow, addflow = inf;
} void ISAP()
{
bool done = false;
addflow = inf, x = s;
while(c[t] != all + 10)
{
if(x == t) aru();
done = false;
for(R i = good[x]; i; i = Next[i])
{
int now = date[i];
good[x] = i;
if(c[now] == c[x] - 1 && haveflow[i])
{
upmin(addflow, haveflow[i]);
last[now] = i, x = now, done = true;
break;
}
} if(!done)
{
int go = all + 9;
for(R i = Head[x]; i; i = Next[i])
if(c[date[i]] && haveflow[i]) upmin(go, c[date[i]]);
good[x] = Head[x];
if(!(-- have[c[x]])) break;
have[c[x] = go + 1] ++;
if(x != s) x = date[last[x] ^ 1];
}
}
printf("%d\n", ans);
} void pre()
{
n = read(), all = n * n + n, s = all + 1, t = s + 1;
for(R i = 1; i <= n; i ++)
for(R j = 1; j <= n; j ++) B[i][j] = read(), ans += B[i][j];
for(R i = 1; i <= n; i ++) C[i] = read();
} inline int id(int i, int j){return (i - 1) * n + j;} void build()
{
for(R i = 1; i <= n; i ++)
for(R j = 1; j <= n; j ++)
{
int ID = id(i, j);
add(s, ID, B[i][j]);
add(ID, n * n + i, inf), add(ID, n * n + j, inf);
}
for(R i = 1; i <= n; i ++) add(n * n + i, t, C[i]);
} int main()
{
// freopen("in.in", "r", stdin);
pre();
build();
bfs();
ISAP();
// fclose(stdin);
return 0;
}

[TJOI2015]线性代数 网络流的更多相关文章

  1. [TJOI2015]线性代数(网络流)

    [TJOI2015]线性代数(最大权闭合子图,网络流) 为了提高智商,ZJY开始学习线性代数.她的小伙伴菠萝给她出了这样一个问题:给定一个n*n的矩阵B和一个1×n的矩阵C.求出一个1×n的01矩阵A ...

  2. 【BZOJ 3996】 3996: [TJOI2015]线性代数 (最小割)

    3996: [TJOI2015]线性代数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1368  Solved: 832 Description 给 ...

  3. bzoj 3996: [TJOI2015]线性代数 [最小割]

    3996: [TJOI2015]线性代数 题意:给出一个NN的矩阵B和一个1N的矩阵C.求出一个1*N的01矩阵A.使得 \(D=(A * B-C)* A^T\)最大.其中A^T为A的转置.输出D.每 ...

  4. BZOJ_3996_[TJOI2015]线性代数_最大权闭合子图

    BZOJ_3996_[TJOI2015]线性代数_最大权闭合子图 Description 给出一个N*N的矩阵B和一个1*N的矩阵C.求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大. ...

  5. 【BZOJ3996】[TJOI2015]线性代数(最小割)

    [BZOJ3996][TJOI2015]线性代数(最小割) 题面 BZOJ 洛谷 题解 首先把式子拆开,发现我们的答案式就是这个: \[\sum_{i=1}^n\sum_{j=1}^n B_{i,j} ...

  6. 【LG3973】[TJOI2015]线性代数

    [LG3973][TJOI2015]线性代数 题面 洛谷 题解 正常解法 一大堆矩阵乘在一起很丑对吧 化一下柿子: \[ D=(A*B-C)*A^T\\ \Leftrightarrow D=\sum_ ...

  7. [Luogu 3973] TJOI2015 线性代数

    [Luogu 3973] TJOI2015 线性代数 这竟然是一道最小割模型. 据说是最大权闭合子图. 先把矩阵式子推出来. 然后,套路建模就好. #include <algorithm> ...

  8. 【BZOJ3996】[TJOI2015]线性代数 最大权闭合图

    [BZOJ3996][TJOI2015]线性代数 Description 给出一个N*N的矩阵B和一个1*N的矩阵C.求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大.其中A^T为A的 ...

  9. 【BZOJ】3996: [TJOI2015]线性代数

    题意 给出一个\(N \times N\)的矩阵\(B\)和一个\(1 \times N\)的矩阵\(C\).求出一个\(1 \times N\)的01矩阵\(A\),使得\[ D = ( A * B ...

随机推荐

  1. Python:静态方法、类方法、实例方法

    1. 静态方法@staticmethod (1)无需自身对象的self参数和自身类的cls参数,可直接通过 类名.方法名 进行调用 (2)Python中并不是真正意义上的静态方法,因为类定义本身就是个 ...

  2. 解决Extjs有IE下z-index属性的问题

    在用Extjs时,有时候,在Google浏览器上面没有任何问题,但是相同的页面在IE下面就会有问题,直接报错,点击中断,进行后可以看到如下的信息: Google里面没这个问题,加一句代码就能解决在窗体 ...

  3. Entity Framework for Oracle 基本配置

    1.需要安装ODAC 如果不安装ODAC,在数据源连接的配置中,看不到Oracle的选项 我下载安装的组件是32-bit Oracle Data Access Components (ODAC)  w ...

  4. 用Python深入理解跳跃表原理及实现

    最近看 Redis 的实现原理,其中讲到 Redis 中的有序数据结构是通过跳跃表来进行实现的.第一次听说跳跃表的概念,感到比较新奇,所以查了不少资料.其中,网上有部分文章是按照如下方式描述跳跃表的: ...

  5. 技本功丨利用 Atomic 构建 React 项目工作流,so easy!

    近日刷微博,#2018年结婚率创新低#荣登热门话题NO.1,沪浙最不积极. 生活压力越大,缺爱的人也越来越多...据本萌的不完全观察,程序猿虽然是压力加成的职业,在袋鼠云还是有不少早早脱了单.至于,脱 ...

  6. 转载笔记:DropDownList无限级分类(灵活控制显示形式)

    主要使用递归实现,数据库结构: 最终样式:  1protected void Page_Load(object sender, EventArgs e) 2    { 3        if (!Pa ...

  7. Python3 迭代器和生成器

    想要搞明白什么是迭代器,首先要了解几个名词:容器(container).迭代(iteration).可迭代对象(iterable).迭代器(iterator).生成器(generator). 看图是不 ...

  8. CSS布局之圣杯布局和双飞翼布局

    其实圣杯布局和双飞翼布局实现的都是三栏布局,两边的盒子宽度固定,中间盒子自适应,也就是我们常说的固比固布局.它们实现的效果都是一样的,差别在于其实现的思想. 一.圣杯布局 html代码中,将重要的内容 ...

  9. “Hello World!”团队第五周第五次会议

    博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 八.checkout&push代码 一.会议时间 2017年11月14日  ...

  10. c# 简单日志记录

    FileStream fs = new FileStream(System.AppDomain.CurrentDomain.BaseDirectory + "log.txt",Fi ...