P4100-[HEOI2013]钙铁锌硒维生素【矩阵求逆,最大匹配】
正题
题目链接:https://www.luogu.com.cn/problem/P4100
题目大意
给出\(n\)个线性无关的向量\(A_i\),然后给出\(n\)个向量\(B_i\),求一个字典序最小的排列\(p\)使得将任意的\(A_i\)替换为\(B_{p_i}\)后依旧线性无关。
\(1\leq n\leq 300\)
解题思路
首先因为我们有\(n\)个向量\(A\)线性无关,那么显然这\(n\)个向量能表示任意向量,如果对于一个\(B_{p_i}\)替换为\(A_i\)后依旧线性无关,那么\(B_{p_i}\)与\(A_i\)是等价的(因为\(B_{p_i}\)和\(A_i\)都代表了剩下\(n-1\)个无法表示的部分)。
所以只需考虑每个\(B_j\)能否换到\(A_i\)即可,构建出矩阵\(A=[A_1,A_2...A_n]\)和\(B=[B_1,B_2...B_n]\),考虑一个置换矩阵使得\(AR=B\),那么就是对于每个\(B\)如何用\(A\)进行表示。
那么如果\(R_{i,j}=0\)也就是说\(B\)可以用\(A_j\)以外的其他\(A\)表示所以\(B\)替换到\(A_j\)之后肯定线性有关了,所以不行。
\(R=\frac{B}{A}\),求逆得到\(R\),这样我们就知道哪些\(A\)可以替换哪些\(B\)了,问题就变成了最小字典序匹配。对于这个问题我们可以考虑找一条增广环就好了。
时间复杂度\(O(n^3)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=310;
const double eps=1e-8;
int n,v[N],link[N];
double A[N][N],B[N][N];
bool GetInv(){
for(int i=1;i<=n;i++){
int z=i;
for(int j=i+1;j<=n;j++)
if(fabs(A[j][i])>fabs(A[z][i]))z=j;
swap(A[i],A[z]);swap(B[i],B[z]);
double x=A[i][i];
if(fabs(x)<eps)return 0;
for(int j=1;j<=n;j++)
A[i][j]/=x,B[i][j]/=x;
for(int j=1;j<=n;j++){
if(i==j)continue;
double rate=-A[j][i];
for(int k=1;k<=n;k++)
A[j][k]+=rate*A[i][k],
B[j][k]+=rate*B[i][k];
}
}
for(int i=n;i>=1;i--)
for(int j=1;j<i;j++){
double rate=-A[j][i];
for(int k=1;k<=n;k++)
A[j][k]+=rate*A[i][k],B[j][k]+=rate*B[i][k];
}
return 1;
}
bool dfs(int x){
for(int i=1;i<=n;i++)
if(!v[i]&&fabs(B[x][i])>=eps){
v[i]=1;
if(!link[i]||dfs(link[i])){
link[i]=x;
return 1;
}
}
return 0;
}
int calc(int x,int top){
for(int i=1;i<=n;i++)
if(!v[i]&&fabs(B[x][i])>=eps){
v[i]=1;
if(link[i]==top||(link[i]>top&&calc(link[i],top))){
link[i]=x;
return i;
}
}
return 0;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%lf",&A[j][i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%lf",&B[j][i]);
if(!GetInv())return puts("NIE")&0;
for(int i=1;i<=n;i++){
memset(v,0,sizeof(v));
if(!dfs(i))return puts("NIE")&0;
}
puts("TAK");
for(int i=1;i<=n;i++){
memset(v,0,sizeof(v));
printf("%d\n",calc(i,i));
}
return 0;
}
P4100-[HEOI2013]钙铁锌硒维生素【矩阵求逆,最大匹配】的更多相关文章
- BZOJ 3168 Luogu P4100 [HEOI2013]钙铁锌硒维生素 (矩阵求逆、二分图匹配)
线性代数+图论好题. 题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=3168 (luogu) https://www.lu ...
- 洛谷 P4100 [HEOI2013]钙铁锌硒维生素 解题报告
P4100 [HEOI2013]钙铁锌硒维生素 题目描述 银河队选手名单出来了!小林,作为特聘的营养师,将负责银河队选手参加 宇宙比赛的饮食. 众所周知,前往宇宙的某个星球,通常要花费好长好长的时间, ...
- BZOJ 3168 Heoi2013 钙铁锌硒维生素 矩阵求逆+匈牙利算法
题目大意:给定一个n∗n的满秩矩阵A和一个n∗n的矩阵B.求一个字典序最小的1...n的排列a满足将随意一个Ai换成Bai后矩阵A仍然满秩 我们考虑建立一个二分图.假设Ai能换成Bj.就在i−> ...
- BZOJ 3168: [Heoi2013]钙铁锌硒维生素 [线性基 Hungary 矩阵求逆]
3168: [Heoi2013]钙铁锌硒维生素 题意:给一个线性无关组A,再给一个B,要为A中每个向量在B中选一个可以代替的向量,替换后仍然线性无关.判断可行和求字典序最小的解 PoPoQQQ orz ...
- 【BZOJ3168】[Heoi2013]钙铁锌硒维生素 高斯消元求矩阵的逆+匈牙利算法
[BZOJ3168][Heoi2013]钙铁锌硒维生素 Description 银河队选手名单出来了!小林,作为特聘的营养师,将负责银河队选手参加宇宙比赛的饮食.众所周知,前往宇宙的某个星球,通常要花 ...
- BZOJ 3168 [Heoi2013]钙铁锌硒维生素 ——矩阵乘法 矩阵求逆
考虑向量ai能否换成向量bj 首先ai都是线性无关的,然后可以a线性表出bj c1*a1+c2*a2+...=bj 然后移项,得 c1/ci*a1+...-1/ci*bj+...=ai 所以当ci不为 ...
- 【BZOJ】3168: [Heoi2013]钙铁锌硒维生素
题解 Ca Fe Zn Se 显然我们既然初始矩阵就能通过线性变换变成单位矩阵,则该矩阵一定有逆 没有逆输出NIE 而且因为这些向量两两正交,则表示一个向量的时候表示方法唯一 那么我们求一个逆可以求出 ...
- BZOJ3168: [Heoi2013]钙铁锌硒维生素
设$A^TC=B^T$,这样$C_{ij}$表示$B_j$的线性表出需要$A_i$,那么$B_j$可以替换$A_i$,根据$C=(A^T)^{-1}B^T$求出$C$.要求字典序最小完美匹配,先求任意 ...
- bzoj3168 钙铁锌硒维生素 (矩阵求逆+二分图最小字典序匹配)
设第一套为A,第二套为B 先对于每个B[i]判断他能否替代A[j],即B[i]与其他的A线性无关 设$B[i]=\sum\limits_{k}{c[k]*A[k]}$,那么只要看c[j]是否等于零即可 ...
- BZOJ3168. [HEOI2013]钙铁锌硒维生素(线性代数+二分图匹配)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3168 题解 首先,我们需要求出对于任意的 \(i, j(1 \leq i, j \leq ...
随机推荐
- Freemarker基本语法
一.概念 Freemarker是一款模板引擎,并用来输出文本,网页或配置文件等. 二.语法 2.1 注释 <!-- 在页面可以看的到 --> <#-- 在页面看不到 --> 2 ...
- mysql删除大表更快的办法
实现:巧用LINK(硬链接),原理:linux文件系统中硬链接相当于文件的入口,记录着ionde的信息.一个文件存在多个硬连接时,删除一个硬链接不会真正的删除ionde(存储文件的数据) # 创建硬链 ...
- 图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)
参考网址:图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS) - 51CTO.COM 深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath ...
- C语言 使用char字符实现汉字处理
系统:windows 64 编译器:gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 文本编辑器:notepa ...
- asp.net core 声明controller的方法
1, 对类名直接添加Controller, 如TestController. 2, 继承Controller 类. 3, 对类名添加controller的属性, 如[Controller]
- 十五:JDBC学习入门
一.JDBC相关概念介绍 1.1.数据库驱动 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡 ...
- 【java虚拟机】垃圾回收机制详解
作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/6486852.html 一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分 ...
- EL表达式学习(二)
1.从特定域中获取值: 2.从请求页面的input标签中,获取值:(同servlet中的getParameter和getParameterValues): 3.获取请求头(同servlet中的getH ...
- go语言内存对齐
内存对齐 为保证程序顺利高效的运行,编译器会把各种类型的数据安排到合适的地址并占用合适的长度,这就是内存对齐 每种类型的对齐值就是他的内存边界 64位 类型 对齐边界 (对齐值) int8 1byte ...
- 再过五分钟,你就懂 HTTP 2.0 了!
Hey guys ,各位小伙伴们大家好,这里是程序员 cxuan,欢迎你收看我最新一期的文章. 这篇文章我们来聊一聊 HTTP 2.0,以及 HTTP 2.0 它在 HTTP 1.1 的基础上做了哪些 ...