【洛谷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矩阵,然后其实就可以 ...
随机推荐
- c/c++ 混合编程.so
CC = gccC++ = g++LINK = g++ LIBS = -lz -lm -lpcre#must add -fPIC optionCCFLAGS = $(COMPILER_FLAGS) - ...
- 并发编程学习笔记(七、Thread源码分析)
目录: 常见属性 构造函数 start() run() 常见属性: /** * 线程名称 */ private volatile String name; /** * 线程优先级 */ private ...
- mysql high severity error 缺少根元素
high severity error 缺少根元素: C:\Users\cf.yu\AppData\Roaming\Oracle\MySQL Notifier里的settings.config.删除他 ...
- leetcode 分类
https://www.douban.com/note/330562764/ https://blog.csdn.net/Irving_zhang/article/details/78835035 h ...
- CF1207F Koala and Notebook(BFS)
你可能会好奇为什么只有一个 BFS 的标签,却还能够排到 F 的位置. 因为它实在是太 简 单 了 有更新 首先,比较两个数,可以先比较两个数的长度,然后比较两个数看成数字串后的字典序. 不妨先把每条 ...
- 在Azure DevOps Server 中提交Maven 依赖包(mvn deploy-file)
Contents 1. 概述 2. 必要准备 安装Java 下载安装Maven 3. 服务器配置 新建连接源 4. 客户端配置 5. 上传maven包文件 6. 常见问题 Maven最新版本3.6.2 ...
- 物联网架构成长之路(44)-Docker私有仓库Harbor
0. 前言 安装docker.docker-compose,这些在我以前的博客讲过,这里就不继续说明了,有需要的可以参考我之前的博客. https://www.cnblogs.com/wunaozai ...
- powershell玩转iis网站服务器
1 ------------安装------------------ for win7,win8,win8.1,win10控制面板--->程序和功能--->开启关闭windows功能--- ...
- lambda的用法
关于lambda的用法: lambda的用法和def的用法基本相同.区别在于def可以用来定义简单和复杂的函数,而lambda主要用来定义简单的函数.下面通过两个例子来了解下: lambda 参数1, ...
- Oracle 11g 服务端的安装步骤
Ø 简介 本文主要介绍 Oracle 11g 服务端的安装步骤,在介绍之前说明以下几点: 1. 所安装的服务器是本机的虚拟机,操作系统为 Windows Server 2019: 2. 以下 ...