1 条题解
-
0
自动搬运
来自洛谷,原作者为

cyffff
Not yet for the story on the last page, it's not the end.搬运于
2025-08-24 21:56:30,当前版本为作者最后更新于2021-07-09 13:46:26,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
:修复一个错误。
题意
给 个线性无关的向量集 和一个向量集 ,求字典序最小的排列 使得将任意的一个 替换为 后,新的向量集依然线性无关。
。
思路
先介绍一下基础知识,会的可以跳过这一段。
线性组合:设在域 中有向量集 ,若有向量 ,其中 ,则 是向量集 的一个线性组合。
线性相关,线性无关:设在域 中有向量集 ,若有一向量 为剩余 个向量的线性组合,则称这 个向量线性相关;反之,则称这 个向量线性无关。
定理 若有 维向量集 线性无关,则所有 维向量都可表示为其线性组合。
即 元 次方程组,有 个方程,可解出唯一解 。
回到这题,我们构建矩阵:
$A=\begin{bmatrix}A_1,A_2,\cdot \cdot \cdot A_n\end{bmatrix},B=\begin{bmatrix}B_1,B_2,\cdot \cdot \cdot B_n\end{bmatrix}$。
由于 ,我们可以把转换系数 也看做矩阵,则有 ,。
此时若 ,则 可以转为 ;反之则不能,因为 时, 是 $A_1\cdot\cdot\cdot A_{i-1}A_{i+1}\cdot\cdot\cdot A_n$ 的线性组合。
那么当 时,由 向 连边建立二分图。
剩余的问题就是二分图最小字典序完美匹配。可以先跑出一组匹配,再使字典序最小。
则在原匹配中有一条增广路径的环上有边 时 的匹配合法,于是找到最小的环即可。
时间复杂度 。
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long namespace IO{//by cyffff } const int N=300+10; const double eps=1e-7; int n; struct Matrix{ double a[N][N]; inline double* operator[](const int &x){ return a[x]; } Matrix(){ memset(a,0,sizeof(a)); } inline void epsilon(){ for(int i=1;i<=n;i++) a[i][i]=1; } inline 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[i][j]+=a.a[i][j]*b.a[j][k]; return c; } inline void swapp(int i,int j){ swap(a[i],a[j]); } }a,b,r; int match[N]; bool vis[N]; inline bool dfs(int x){ for(int t=1;t<=n;t++){ if(!vis[t]&&fabs(r[x][t])>eps){ vis[t]=true; if(!match[t]||dfs(match[t])){ match[t]=x; return true; } } } return false; } inline int dfs(int x,int tp){ for(int t=1;t<=n;t++){ if(!vis[t]&&fabs(r[x][t])>eps){ vis[t]=true; if(match[t]==tp||(match[t]>tp&&dfs(match[t],tp))){ match[t]=x; return t; } } } return 0; } int main(){ n=read(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[j][i]=(double)read(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) b[j][i]=(double)read(); r.epsilon(); for(int i=1;i<=n;i++){ int k=i; for(int j=i+1;j<=n;j++) if(fabs(a[j][i])>fabs(a[k][i])) k=j; if(fabs(a[k][i])<eps){ puts("NIE"); return 0; } if(k!=i) a.swapp(i,k), b.swapp(i,k); double x=a[i][i]; 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){ double res=a[j][i]; for(int k=1;k<=n;k++) a[j][k]-=a[i][k]*res, b[j][k]-=b[i][k]*res; } } r=b; for(int i=1;i<=n;i++){ memset(vis,0,sizeof(vis)); if(!dfs(i)) return puts("NIE"),0; } puts("TAK"); for(int i=1;i<=n;i++){ memset(vis,0,sizeof(vis)); write(dfs(i,i)),putc('\n'); } flush(); }再见 qwq~
- 1
信息
- ID
- 3057
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 7
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者