设第一套为A,第二套为B

先对于每个B[i]判断他能否替代A[j],即B[i]与其他的A线性无关

设$B[i]=\sum\limits_{k}{c[k]*A[k]}$,那么只要看c[j]是否等于零即可,如果c[j]=0,就意味着可以用A[j]以外的线性表达出B[i],所以不能B[i]替换A[j],否则可以

于是高斯消元求出c矩阵,问题就转化成了求二分图的最小字典序匹配

先跑一遍匈牙利判下是否无解,然后以它为基准解再贪心地求一遍答案

具体地说,你做到第i个的时候,前i-1都要固定住,其他的和普通匈牙利是一样的

 #include<bits/stdc++.h>
#include<tr1/unordered_map>
#define CLR(a,x) memset(a,x,sizeof(a))
#define MP make_pair
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pa;
typedef long double ld;
const int maxn=,P=; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N;
int a[maxn][maxn*],b[maxn][maxn],c[maxn][maxn];
bool can[maxn][maxn]; inline int fpow(int x,int y){
int re=;
while(y){
if(y&) re=1ll*x*re%P;
x=1ll*x*x%P,y>>=;
}return re;
} inline void getinv(){
for(int i=;i<=N;i++){
a[i][i+N]=;
}
for(int i=;i<=N;i++){
int mi=i;
for(int j=i+;j<=N;j++) if(a[j][i]) mi=j;
swap(a[mi],a[i]);
int iv=fpow(a[i][i],P-);
for(int j=N*;j>=i;j--) a[i][j]=1ll*a[i][j]*iv%P;
for(int j=i+;j<=N;j++){
for(int k=N*;k>=i;k--) a[j][k]=(a[j][k]-1ll*a[i][k]*a[j][i])%P;
}
}
for(int i=N;i;i--){
for(int j=i-;j;j--){
for(int k=N+;k<=N*;k++) a[j][k]=(a[j][k]-1ll*a[j][i]*a[i][k])%P;
}
}
for(int i=;i<=N;i++){
for(int j=;j<=N;j++) a[i][j]=a[i][j+N];
}
} int bel[maxn],to[maxn];bool flag[maxn]; bool dfs(int x){
for(int i=;i<=N;i++){
if(!can[x][i]||flag[i]) continue;
flag[i]=;
if(!bel[i]||dfs(bel[i])){bel[i]=x,to[x]=i;return ;}
}return ;
}
bool dfs2(int x,int y){
for(int i=;i<=N;i++){
if(!can[x][i]||flag[i]) continue;
flag[i]=;
if(bel[i]==y||(bel[i]>y&&dfs2(bel[i],y))){to[x]=i,bel[i]=x;return ;}
}return ;
} int main(){
//freopen("","r",stdin);
N=rd();
for(int i=;i<=N;i++){
for(int j=;j<=N;j++) a[i][j]=rd();
}
for(int i=;i<=N;i++){
for(int j=;j<=N;j++) b[i][j]=rd();
}
getinv();
for(int i=;i<=N;i++){
for(int j=;j<=N;j++){
for(int k=;k<=N;k++){
c[i][j]=(c[i][j]+1ll*b[i][k]*a[k][j])%P;
}
}
}
for(int i=;i<=N;i++){
for(int j=;j<=N;j++){
if(c[i][j]) can[j][i]=;
}
}/*
for(int i=rd();i;i--){
int a=rd(),b=rd();
can[a][b]=1;
}*/
bool bl=;
for(int i=;i<=N;i++){
CLR(flag,);
if(!dfs(i)){bl=;break;}
}
if(!bl) printf("NIE\n");
else{
printf("TAK\n");
for(int i=;i<=N;i++){
CLR(flag,);
dfs2(i,i);
}
for(int i=;i<=N;i++){
printf("%d\n",to[i]);
}
}
return ;
}

bzoj3168 钙铁锌硒维生素 (矩阵求逆+二分图最小字典序匹配)的更多相关文章

  1. [模板] 匈牙利算法&&二分图最小字典序匹配

    匈牙利算法 简介 匈牙利算法是一种求二分图最大匹配的算法. 时间复杂度: 邻接表/前向星: \(O(n * m)\), 邻接矩阵: \(O(n^3)\). 空间复杂度: 邻接表/前向星: \(O(n ...

  2. HDU 1533:Going Home(KM算法求二分图最小权匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 Going Home Problem Description   On a grid map there ...

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

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

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

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

  5. HDU 1533 二分图最小权匹配 Going Home

    带权二分图匹配,把距离当做权值,因为是最小匹配,所以把距离的相反数当做权值求最大匹配. 最后再把答案取一下反即可. #include <iostream> #include <cst ...

  6. [ACM] POJ 3686 The Windy&#39;s (二分图最小权匹配,KM算法,特殊建图)

    The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4158   Accepted: 1777 Descr ...

  7. [ACM] HDU 1533 Going Home (二分图最小权匹配,KM算法)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  8. P4100-[HEOI2013]钙铁锌硒维生素【矩阵求逆,最大匹配】

    正题 题目链接:https://www.luogu.com.cn/problem/P4100 题目大意 给出\(n\)个线性无关的向量\(A_i\),然后给出\(n\)个向量\(B_i\),求一个字典 ...

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

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

随机推荐

  1. Identity4实现服务端+api资源控制+客户端请求

    准备写一些关于Identity4相关的东西,最近也比较对这方面感兴趣.所有做个开篇笔记记录一下,以便督促自己下一个技术方案方向 已经写好的入门级别Identity4的服务+api资源访问控制和简单的客 ...

  2. 基础知识:编程语言介绍、Python介绍、Python解释器安装、运行Python解释器的两种方式、变量、数据类型基本使用

    2018年3月19日 今日学习内容: 1.编程语言的介绍 2.Python介绍 3.安装Python解释器(多版本共存) 4.运行Python解释器程序两种方式.(交互式与命令行式)(♥♥♥♥♥) 5 ...

  3. 九九乘法表-for循环

    1.打印在左上角 #直角在左上方 for i in range(9,0,-1): for j in range(1,10): if j <= i: print("{}*{}={}&qu ...

  4. Tkinter小技巧:如何为窗口右上角的‘x’添加一个自定义的响应函数

    不废话,直接上代码 import tkinter as tk from tkinter import messagebox main_window = tk.Tk() main_window.geom ...

  5. K3实现按虚拟件/组件发料

           最近公司调度部反应了一个K3使用过程中遇到的巨大问题:公司成品BOM组成物料种类破千,绝大部分还不能拆分成组件.为了方便区分,从逻辑上把一堆堆的半成品分成了一个个虚拟件.K3生成的投料单 ...

  6. dotnet core如何编译exe

    dotnet core 有一个转变,他用dll格式来代替exe作为通用执行格式,然后要命令行dotnet yourApp.dll 来运行程序.为了提高逼格,双击可以运行,可以采用以下方案: 方案一 用 ...

  7. springCloud feign使用/优化总结

    基于springCloud Dalston.SR3版本 1.当接口参数是多个的时候 需要指定@RequestParam 中的value来明确一下. /** * 用户互扫 * @param uid 被扫 ...

  8. VS2017的MVC和Angular联合开发的配置文件作用

    在通过MVC和Angular联合开发项目时,项目里有几个重要的配置文件,下面列出这几个配置文件的分析和比较: 主要配置文件有appsettings.json,tsconfig.json,package ...

  9. python3 haproxy配置文件操作练习

    哈哈 老规矩 先来一个NLP第六条:咳咳! 六,重复旧的做法,只会得到旧的结果   做法有不同,结果才会有不同. 如果,你的事没有结果,改变你的做法.任何新的做法,都比旧的多一份成功的机会. 想明天比 ...

  10. 转://oracle 软件的收费模式

    Oracle软件本身是免费的,所以任何人都可以从Oracle官方网站下载并安装Oracle的数据库软件,收费的是License,即软件授权,如果数据库用于商业用途,就需要购买相应Oracle产品的Li ...