【洛谷P3973】[TJOI2015]线性代数(最小割)
题意:
给出一个\(n*n\)的矩阵\(B\),再给出一个\(1*n\)的矩阵\(C\)。
求一个\(1*n\)的\(01\)矩阵\(A\),使得\(D=(A\cdot B-C)\cdot A^T\)最大。
思路:
化简最后得:
\]
之后考虑所有的\(A_i\)都为\(1\),现在要将一部分\(A_i\)变为\(0\),最后的损失最小。
因为最后的\(A\)为\(01\)矩阵,显然最后结果为一个集合;结合损失最小,考虑最小割。
式子中只与\(A_i,A_j\)两个元素有关,单独考虑这两个元素,发现是一个很经典的最小割模型。然后解下方程就没了。
代码如下:
/*
* Author: heyuhhh
* Created Time: 2019/10/29 17:17:13
*/
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 500 + 5;
int n;
int a[N][N];
template <class T>
struct Dinic{
struct Edge{
int v, next;
T flow;
Edge(){}
Edge(int v, int next, T flow) : v(v), next(next), flow(flow) {}
}e[N * N * 10];
int head[N], tot;
int dep[N];
void init() {
memset(head, -1, sizeof(head)); tot = 0;
}
void adde(int u, int v, T w, T rw = 0) {
e[tot] = Edge(v, head[u], w);
head[u] = tot++;
e[tot] = Edge(u, head[v], rw);
head[v] = tot++;
}
bool BFS(int _S, int _T) {
memset(dep, 0, sizeof(dep));
queue <int> q; q.push(_S); dep[_S] = 1;
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = head[u]; ~i; i = e[i].next) {
int v = e[i].v;
if(!dep[v] && e[i].flow > 0) {
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return dep[_T] != 0;
}
T dfs(int _S, int _T, T a) {
T flow = 0, f;
if(_S == _T || a == 0) return a;
for(int i = head[_S]; ~i; i = e[i].next) {
int v = e[i].v;
if(dep[v] != dep[_S] + 1) continue;
f = dfs(v, _T, min(a, e[i].flow));
if(f) {
e[i].flow -= f;
e[i ^ 1].flow += f;
flow += f;
a -= f;
if(a == 0) break;
}
}
if(!flow) dep[_S] = -1;
return flow;
}
T dinic(int _S, int _T) {
T max_flow = 0;
while(BFS(_S, _T)) max_flow += dfs(_S, _T, INF);
return max_flow;
}
};
Dinic <int> solver;
int c[N], v[N];
void run() {
solver.init();
cin >> n;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
cin >> a[i][j];
}
}
for(int i = 1; i <= n; i++) cin >> c[i];
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) v[i] += a[i][j] + a[j][i];
v[i] -= a[i][i];
v[i] <<= 1;
}
int S = 0, T = n + 1;
for(int i = 1; i <= n; i++) {
int t = 0;
for(int j = 1; j <= n; j++) {
if(i != j) {
solver.adde(i, j, a[i][j] + a[j][i]);
t += v[i] - a[i][j] - a[j][i];
}
}
solver.adde(i, T, 2 * c[i]);
solver.adde(S, i, t);
}
int ans = 0;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
ans += a[i][j];
}
}
int flow = solver.dinic(S, T);
dbg(ans, flow);
cout << (ans - flow / 2) << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
freopen("../input.in", "r", stdin);
freopen("../output.out", "w", stdout);
run();
return 0;
}
【洛谷P3973】[TJOI2015]线性代数(最小割)的更多相关文章
- 洛谷P3973 - [TJOI2015]线性代数
Portal Description 给定一个\(n\times n\)的矩阵\(B\)和一个\(1×n\)的矩阵\(C\).求出一个\(1×n\)的01矩阵\(A\),使得\(D=(A×B-C)×A ...
- bzoj 3996: [TJOI2015]线性代数 [最小割]
3996: [TJOI2015]线性代数 题意:给出一个NN的矩阵B和一个1N的矩阵C.求出一个1*N的01矩阵A.使得 \(D=(A * B-C)* A^T\)最大.其中A^T为A的转置.输出D.每 ...
- 【洛谷P3329】 [ZJOI2011]最小割(最小割树)
洛谷 题意: 给出一个无向图,之后有\(q,q\leq 30\)组询问,每组询问有一个\(x\),回答有多少点对\((a,b)\)其\(a-b\)最小割不超过\(x\). 思路: 这个题做法要最小割树 ...
- [TJOI2015]线性代数(最小割)
题目描述 给出一个N*N的矩阵B和一个1*N的矩阵C.求出一个1*N的01矩阵A.使得 D=(A*B-C)*A^T最大.其中A^T为A的转置.输出D 题解 观察上面那个式子发现,当一个bij有贡献时当 ...
- 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矩阵, ...
- 洛谷3973 TJOI2015线性代数(最小割+思维)
感觉要做出来这个题,需要一定的线代芝士 首先,我们来观察这个柿子. 我们将\(B\)的权值看作是收益的话,\(C\)的权值就是花费. 根据矩阵乘法的原理,只有当\(a[i]和a[j]\)都为\(1\) ...
- bzoj 3996 [TJOI2015]线性代数——最小割
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3996 b[ i ][ j ] 要计入贡献,当且仅当 a[ i ] = 1 , a[ j ] ...
- 洛谷P4014 分配问题【最小/大费用流】题解+AC代码
洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...
- 洛谷 [P3973] 线性代数
最大权闭合子图,神题 这不是线性代数,这是网络流. 我们看见这是一堆矩阵的运算,而且最后变成了一个数,那么我们就想到,把这个矩阵乘法的过程用具体的数字推出来 我们发现,a是一个01矩阵,然后其实就可以 ...
随机推荐
- socket.error: [Errno 10048]
socket.error: [Errno 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次 经过搜索发现这个提示是在端口冲突的时候出现,可能的原因是在服务器程序中创建一个Sock ...
- css 文本外观属性(text) 和 字体样式属性(font)
css文本 text外观属性 color: 颜色值(red,blue)十六进制 ,rgb letter-spacing: 字间距 px,em word-spacing: 单词间距 对中文无效 line ...
- day71_10_16多表断关联
---恢复内容开始--- 本次环境: 配置settings INSTALLED_APPS = [ # ... 'rest_framework', ] DATABASES = { 'default': ...
- 【Spring AOP】AOP实现原理(六)
原文链接:https://my.oschina.net/guangshan/blog/1797461
- django自定义错误处理
要实现自定义错误处理的功能,总共分4步: 1.创建html错误页 2.配置settings ,当DEBUG=True,则不会生效 3.编写视图 4.配置url views.py def page_ ...
- dirb参数解析
-----------------DIRB v2.22 By The Dark Raver----------------- dirb <url_base> [<wordlist_f ...
- 【cf比赛记录】Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)
比赛传送门 只能说当晚状态不佳吧,有点头疼感冒的症状.也跟脑子没转过来有关系,A题最后一步爆搜没能立即想出来,B题搜索没有用好STL,C题也因为前面两题弄崩了心态,最后,果然掉分了. A:简单数学 B ...
- 在net Core3.1上基于winform实现依赖注入实例
目录 在net Core3.1上基于winform实现依赖注入实例 1.背景 2.依赖注入 2.1依赖注入是什么? 2.1依赖注入的目的 2.2依赖注入带来的好处 2.2.1生命周期的控制 2.2.2 ...
- Module Code: CMT107
Cardiff School of Computer Science and InformaticsCoursework Assessment Pro-formaModule Code: CMT107 ...
- vue项目打包之后样式错乱问题,如何处理
最近公司做的这个项目,要大量修改element里面的css样式,所以项目打包之后 会出现样式和本地开发的时候样式有很多不一样,原因可能是css加载顺序有问题,样式被覆改了. 所以在mian.js里面这 ...