正题

题目链接: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]钙铁锌硒维生素【矩阵求逆,最大匹配】的更多相关文章

  1. BZOJ 3168 Luogu P4100 [HEOI2013]钙铁锌硒维生素 (矩阵求逆、二分图匹配)

    线性代数+图论好题. 题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=3168 (luogu) https://www.lu ...

  2. 洛谷 P4100 [HEOI2013]钙铁锌硒维生素 解题报告

    P4100 [HEOI2013]钙铁锌硒维生素 题目描述 银河队选手名单出来了!小林,作为特聘的营养师,将负责银河队选手参加 宇宙比赛的饮食. 众所周知,前往宇宙的某个星球,通常要花费好长好长的时间, ...

  3. BZOJ 3168 Heoi2013 钙铁锌硒维生素 矩阵求逆+匈牙利算法

    题目大意:给定一个n∗n的满秩矩阵A和一个n∗n的矩阵B.求一个字典序最小的1...n的排列a满足将随意一个Ai换成Bai后矩阵A仍然满秩 我们考虑建立一个二分图.假设Ai能换成Bj.就在i−> ...

  4. BZOJ 3168: [Heoi2013]钙铁锌硒维生素 [线性基 Hungary 矩阵求逆]

    3168: [Heoi2013]钙铁锌硒维生素 题意:给一个线性无关组A,再给一个B,要为A中每个向量在B中选一个可以代替的向量,替换后仍然线性无关.判断可行和求字典序最小的解 PoPoQQQ orz ...

  5. 【BZOJ3168】[Heoi2013]钙铁锌硒维生素 高斯消元求矩阵的逆+匈牙利算法

    [BZOJ3168][Heoi2013]钙铁锌硒维生素 Description 银河队选手名单出来了!小林,作为特聘的营养师,将负责银河队选手参加宇宙比赛的饮食.众所周知,前往宇宙的某个星球,通常要花 ...

  6. BZOJ 3168 [Heoi2013]钙铁锌硒维生素 ——矩阵乘法 矩阵求逆

    考虑向量ai能否换成向量bj 首先ai都是线性无关的,然后可以a线性表出bj c1*a1+c2*a2+...=bj 然后移项,得 c1/ci*a1+...-1/ci*bj+...=ai 所以当ci不为 ...

  7. 【BZOJ】3168: [Heoi2013]钙铁锌硒维生素

    题解 Ca Fe Zn Se 显然我们既然初始矩阵就能通过线性变换变成单位矩阵,则该矩阵一定有逆 没有逆输出NIE 而且因为这些向量两两正交,则表示一个向量的时候表示方法唯一 那么我们求一个逆可以求出 ...

  8. BZOJ3168: [Heoi2013]钙铁锌硒维生素

    设$A^TC=B^T$,这样$C_{ij}$表示$B_j$的线性表出需要$A_i$,那么$B_j$可以替换$A_i$,根据$C=(A^T)^{-1}B^T$求出$C$.要求字典序最小完美匹配,先求任意 ...

  9. bzoj3168 钙铁锌硒维生素 (矩阵求逆+二分图最小字典序匹配)

    设第一套为A,第二套为B 先对于每个B[i]判断他能否替代A[j],即B[i]与其他的A线性无关 设$B[i]=\sum\limits_{k}{c[k]*A[k]}$,那么只要看c[j]是否等于零即可 ...

  10. BZOJ3168. [HEOI2013]钙铁锌硒维生素(线性代数+二分图匹配)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3168 题解 首先,我们需要求出对于任意的 \(i, j(1 \leq i, j \leq ...

随机推荐

  1. Freemarker基本语法

    一.概念 Freemarker是一款模板引擎,并用来输出文本,网页或配置文件等. 二.语法 2.1 注释 <!-- 在页面可以看的到 --> <#-- 在页面看不到 --> 2 ...

  2. mysql删除大表更快的办法

    实现:巧用LINK(硬链接),原理:linux文件系统中硬链接相当于文件的入口,记录着ionde的信息.一个文件存在多个硬连接时,删除一个硬链接不会真正的删除ionde(存储文件的数据) # 创建硬链 ...

  3. 图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)

    参考网址:图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS) - 51CTO.COM 深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath ...

  4. C语言 使用char字符实现汉字处理

    系统:windows 64 编译器:gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 文本编辑器:notepa ...

  5. asp.net core 声明controller的方法

    1, 对类名直接添加Controller, 如TestController. 2,  继承Controller 类. 3, 对类名添加controller的属性, 如[Controller]

  6. 十五:JDBC学习入门

    一.JDBC相关概念介绍 1.1.数据库驱动 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡 ...

  7. 【java虚拟机】垃圾回收机制详解

    作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/6486852.html 一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分 ...

  8. EL表达式学习(二)

    1.从特定域中获取值: 2.从请求页面的input标签中,获取值:(同servlet中的getParameter和getParameterValues): 3.获取请求头(同servlet中的getH ...

  9. go语言内存对齐

    内存对齐 为保证程序顺利高效的运行,编译器会把各种类型的数据安排到合适的地址并占用合适的长度,这就是内存对齐 每种类型的对齐值就是他的内存边界 64位 类型 对齐边界 (对齐值) int8 1byte ...

  10. 再过五分钟,你就懂 HTTP 2.0 了!

    Hey guys ,各位小伙伴们大家好,这里是程序员 cxuan,欢迎你收看我最新一期的文章. 这篇文章我们来聊一聊 HTTP 2.0,以及 HTTP 2.0 它在 HTTP 1.1 的基础上做了哪些 ...