【BZOJ】3168: [Heoi2013]钙铁锌硒维生素
题解
显然我们既然初始矩阵就能通过线性变换变成单位矩阵,则该矩阵一定有逆
没有逆输出NIE
而且因为这些向量两两正交,则表示一个向量的时候表示方法唯一
那么我们求一个逆可以求出这个矩阵消成单位矩阵的线性表示,再拿第二个矩阵和逆矩阵相乘可以得到第二个矩阵每个行向量用第一个矩阵的行向量唯一的表示方法
如果第二套的第k个行向量的表示里第一行h个行向量系数不为0,则h可以被k替代
建图二分图匹配,先求一个匹配出来,然后对于每个点从前往后固定匹配看看能不能使得靠前的更小
说的很高端吧
算了我简单一点说
就是一考虑初始的矩阵,什么两三行加加减减乘个系数,是可以消成单位1的,这个可以用类似高斯消元的方法解决,实际上如果你了解矩阵求逆的话你就知道我在给这个矩阵求逆矩阵
如果消不成就是NIE了
如果你不了解的话,你可以把每次变换每个行所用到的系数记下来,变成另一个矩阵\(B\)
那么我们考虑第二套的某个向量,
\((b_{1},b_{2}...b_{n}) = \sum_{i = 1}^{n} c_{i} (a_{1},a_{2}..a_{n})\)
显然如果\(c_{i}\)有数的话,我门可以把\(c_{i}\)移到等号左边,把第二套的这个向量移到等式右边,就证明\(i\)可以被这个向量换掉了
这个系数可以用两个矩阵相乘求出来
图建出来了,那就是跑二分图了
我们先求出一个完备匹配来,没有就是NIE,有的话对于\(1-n\)从小到大枚举能更新的匹配点,然后把这个点强制不选再跑二分图看看会不会合法
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define mo 974711
#define MAXN 305
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int N;
int g[305][305],matc[305],matk[305];
bool vis[305];
bool flag = 0;
struct Matrix {
db f[305][305];
Matrix() {memset(f,0,sizeof(f));}
void unit() {
for(int i = 1 ; i <= N ; ++i) {
f[i][i] = 1.0;
}
}
friend Matrix operator * (const Matrix &a,const Matrix &b) {
Matrix c;
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= N ; ++j) {
for(int k = 1 ; k <= N ; ++k) {
c.f[i][j] += a.f[i][k] * b.f[k][j];
}
}
}
return c;
}
friend Matrix operator ~(Matrix a) {
Matrix b;
b.unit();
for(int i = 1 ; i <= N ; ++i) {
int l = i;
for(int j = i + 1; j <= N ; ++j) {
if(fabs(a.f[j][i]) > fabs(a.f[l][i])) l = j;
}
if(fabs(a.f[l][i]) < 1e-8) {flag = 1;return b;}
if(i != l) {
for(int j = 1 ; j <= N ; ++j) {
swap(a.f[i][j],a.f[l][j]);
swap(b.f[i][j],b.f[l][j]);
}
}
db t = 1.0 / a.f[i][i];
for(int j = 1 ; j <= N ; ++j) {
a.f[i][j] *= t;
b.f[i][j] *= t;
}
for(int j = 1 ; j <= N ; ++j) {
if(i == j) continue;
db t = a.f[j][i];
for(int k = 1 ; k <= N ; ++k) {
a.f[j][k] -= t * a.f[i][k];
b.f[j][k] -= t * b.f[i][k];
}
}
}
return b;
}
}A,B,C;
bool match(int u) {
for(int i = 1 ; i <= N ; ++i) {
if(g[u][i]) {
if(!vis[i]) {
vis[i] = 1;
if(!matc[i] || match(matc[i])) {
matc[i] = u;matk[u] = i;
return true;
}
}
}
}
return false;
}
void Solve() {
read(N);
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= N ; ++j) {
scanf("%lf",&A.f[i][j]);
}
}
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= N ; ++j) {
scanf("%lf",&C.f[i][j]);
}
}
B = ~A;
if(flag) {
puts("NIE");return;
}
C = C * B;
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= N ; ++j) {
if(fabs(C.f[i][j]) > 1e-8) {
g[j][i] = 1;
}
}
}
for(int i = 1 ; i <= N ; ++i) {
memset(vis,0,sizeof(vis));
if(!match(i)) {
puts("NIE");return;
}
}
puts("TAK");
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= N ; ++j) {
if(!g[i][j]) continue;
if(matk[i] == j) break;
if(matc[j] < i) continue;
memset(vis,0,sizeof(vis));
for(int k = 1 ; k < i ; ++k) vis[matk[k]] = 1;
vis[j] = 1;
int t = matk[i];
matc[t] = 0;
if(match(matc[j])) {
matk[i] = j;matc[j] = i;
break;
}
else {
matc[t] = i;
}
}
}
for(int i = 1 ; i <= N ; ++i) {
out(matk[i]);enter;
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}
【BZOJ】3168: [Heoi2013]钙铁锌硒维生素的更多相关文章
- BZOJ 3168: [Heoi2013]钙铁锌硒维生素 [线性基 Hungary 矩阵求逆]
3168: [Heoi2013]钙铁锌硒维生素 题意:给一个线性无关组A,再给一个B,要为A中每个向量在B中选一个可以代替的向量,替换后仍然线性无关.判断可行和求字典序最小的解 PoPoQQQ orz ...
- BZOJ 3168 Heoi2013 钙铁锌硒维生素 矩阵求逆+匈牙利算法
题目大意:给定一个n∗n的满秩矩阵A和一个n∗n的矩阵B.求一个字典序最小的1...n的排列a满足将随意一个Ai换成Bai后矩阵A仍然满秩 我们考虑建立一个二分图.假设Ai能换成Bj.就在i−> ...
- BZOJ 3168 [Heoi2013]钙铁锌硒维生素 ——矩阵乘法 矩阵求逆
考虑向量ai能否换成向量bj 首先ai都是线性无关的,然后可以a线性表出bj c1*a1+c2*a2+...=bj 然后移项,得 c1/ci*a1+...-1/ci*bj+...=ai 所以当ci不为 ...
- 洛谷 P4100 [HEOI2013]钙铁锌硒维生素 解题报告
P4100 [HEOI2013]钙铁锌硒维生素 题目描述 银河队选手名单出来了!小林,作为特聘的营养师,将负责银河队选手参加 宇宙比赛的饮食. 众所周知,前往宇宙的某个星球,通常要花费好长好长的时间, ...
- 【BZOJ3168】[Heoi2013]钙铁锌硒维生素 高斯消元求矩阵的逆+匈牙利算法
[BZOJ3168][Heoi2013]钙铁锌硒维生素 Description 银河队选手名单出来了!小林,作为特聘的营养师,将负责银河队选手参加宇宙比赛的饮食.众所周知,前往宇宙的某个星球,通常要花 ...
- BZOJ 3168 Luogu P4100 [HEOI2013]钙铁锌硒维生素 (矩阵求逆、二分图匹配)
线性代数+图论好题. 题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=3168 (luogu) https://www.lu ...
- BZOJ3168. [HEOI2013]钙铁锌硒维生素(线性代数+二分图匹配)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3168 题解 首先,我们需要求出对于任意的 \(i, j(1 \leq i, j \leq ...
- BZOJ3168: [Heoi2013]钙铁锌硒维生素
设$A^TC=B^T$,这样$C_{ij}$表示$B_j$的线性表出需要$A_i$,那么$B_j$可以替换$A_i$,根据$C=(A^T)^{-1}B^T$求出$C$.要求字典序最小完美匹配,先求任意 ...
- bzoj 3165: [Heoi2013]Segment 动态凸壳
3165: [Heoi2013]Segment Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 202 Solved: 89[Submit][Stat ...
随机推荐
- 洛谷P3385 【模板】负环(DFS求环)
洛谷题目传送门 HNOI爆零前回刷模板题 非常不正经的题目,目前并没有合适的优秀算法,就算是大家公认的dfs(还是不要强行叫dfs-spfa吧,概念应该不一样,这就是暴力dfs松弛答案) 但是对于随机 ...
- c++并发编程之线程的互斥与同步
什么是线程的同步与互斥? 互斥:指在某一时刻指允许一个进程运行其中的程序片,具有排他性和唯一性. 对于线程A和线程B来讲,在同一时刻,只允许一个线程对临界资源进行操作,即当A进入临界区对资源操作时,B ...
- php Mockery 错误 "call_user_func_array() expects parameter 1 to be a valid callback, class 'Mockery\Expectation' does not have a method"
错误写法 $mock = Mockery::mock(MyClass::class) ->shouldReceive('foo') ->once() ->with($arg) -&g ...
- linux command ------ dmesg
驱动开发中使用函数 printk() 打印的信息可以通过 dmesg 查看 简介 ‘dmesg’命令显示linux内核的环形缓冲区信息,我们可以从中获得诸如系统架构.cpu.挂载的硬件,RAM等多个运 ...
- P3173 [HAOI2009]巧克力 && P1324 矩形分割
题目描述 出于某些方面的需求,我们要把一块N×M的木板切成一个个1×1的小方块. 对于一块木板,我们只能从某条横线或者某条竖线(要在方格线上),而且这木板是不均匀的,从不同的线切割下去要花不同的代价. ...
- hdu 5956 The Elder
http://acm.hdu.edu.cn/showproblem.php?pid=5956 转移方程:dp[i]=(dis[i]-dis[j])*(dis[i]-dis[j])+P+dp[j] 斜率 ...
- linux解压
tar –xvf file.tar //解压 tar包tar -xzvf file.tar.gz //解压tar.gztar -xjvf file.tar.bz2 //解压 tar.bz2tar –x ...
- spark RDD 常见操作
fold 操作 区别 与 co 1.mapValus 2.flatMapValues 3.comineByKey 4.foldByKey 5.reduceByKey 6.groupByKey 7.so ...
- 前三章 man手册 查看文件
1 – 3章 1.1 man手册: 分1 - 9个区域,可以认为是一个一个小节 把man手册理解为一本书 第一节:可执行程序或shell命令 第二节:系统调用 第三节:库调用 第四节:特殊文件 第五节 ...
- Strange Queries(莫队)
题目 You are given an array with n integers a1, a2, ..., an, and q queries to answer. Each query consi ...