【BZOJ3168】[Heoi2013]钙铁锌硒维生素 高斯消元求矩阵的逆+匈牙利算法
【BZOJ3168】[Heoi2013]钙铁锌硒维生素
Description
Input
Output
Sample Input
1 0 0
0 1 0
0 0 1
2 3 0
0 7 8
0 0 9
Sample Output
1
2
3
题解:要不是有大爷的题解我还真就不一定能看懂题意。。。
题目大意:给定一个n∗n的满秩矩阵A和一个n∗n的矩阵B,求一个字典序最小的1...n的排列a满足将任意一个Ai换成Bai后矩阵A仍然满秩。
是不是清晰多了?求这样的排列实际上是将A乘上一个矩阵C使得CA=B,C=BA-1。
求出来C后,我们改变思路,将用边i->j表示B中j号机器人能替换A中i号机器人,然后就得到了一个二分图,而CT正好是二分图的邻接矩阵,我们想求二分图的字典序最小的完美匹配。
一开始以为大爷做麻烦了,直接从后往前做一遍匈牙利算法就行,直到我看了Discuss。。。好吧还是要做两边,第一遍正常跑,第二遍贪心的选编号小的,并且要求后面的点不能影响前面的点。
这里依旧是做一下大爷博客的注释:
1.为什么是CA=B而不是AC=B???(我一开始也死活搞不懂)
因为每个机器人对应一个行向量,而我们想让A中的行向量对应B中另外一个行向量,这显然直接矩乘是不行的,但如果我们将A,B分别转置,就可以做到A中一个列向量对应B中另外一个列向量,然后就是ATC=BT(这里的C指的就是二分图的邻接矩阵),等价于CTA=B
2.不影响前面的交错环是什么鬼?(或者你认为我说的也不是那么清楚?)
直接说方法吧:在第二遍DFS的时候记录一下当前是从那个点开始去寻找增广路的,也就意味着编号比这个点小的点我们都不能影响。所以我们看一下B中的机器人所对应的A中的机器人的编号,如果编号<起始点,就不能更改;如果编号=起始点,而我们已经向让起始点和其它点匹配了,这个点就已经被闲置出来了,就可以更改;如果编号>起始点,那么我们继续寻找增广路就行了。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#define mod 999911657
using namespace std;
const double eps=1e-6;
typedef long long ll;
int n,ans;
ll A[310][610],B[310][310],C[310][310];
int vis[310],from[310],to[310];
ll pm(ll x,ll y)
{
ll z=1;
while(y)
{
if(y&1) z=z*x%mod;
x=x*x%mod,y>>=1;
}
return z;
}
int rd()
{
int ret=0; char gc=getchar();
while(gc<'0'||gc>'9') gc=getchar();
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret;
}
int dfs1(int x)
{
for(int i=1;i<=n;i++)
{
if(C[i][x]&&!vis[i])
{
vis[i]=1;
if(!from[i]||dfs1(from[i]))
{
to[x]=i,from[i]=x;
return 1;
}
}
}
return 0;
}
int dfs2(int x,int y)
{
for(int i=1;i<=n;i++)
{
if(C[i][x]&&!vis[i])
{
vis[i]=1;
if(from[i]==y||(from[i]>y&&dfs2(from[i],y)))
{
from[i]=x,to[x]=i;
return 1;
}
}
}
return 0;
}
int main()
{
n=rd();
int i,j,k;
for(i=1;i<=n;i++) for(j=1;j<=n;j++) A[i][j]=rd(),A[i][j+n]=(i==j);
for(i=1;i<=n;i++) for(j=1;j<=n;j++) B[i][j]=rd();
ll t;
for(i=1;i<=n;i++)
{
for(j=i;j<=n;j++) if(A[j][i])
{
for(k=1;k<=2*n;k++) swap(A[i][k],A[j][k]);
break;
}
t=pm(A[i][i],mod-2);
for(k=i;k<=2*n;k++) A[i][k]=A[i][k]*t%mod;
for(j=1;j<=n;j++) if(i!=j)
{
t=A[j][i];
for(k=1;k<=2*n;k++) A[j][k]=(A[j][k]-t*A[i][k]%mod+mod)%mod;
}
}
for(i=1;i<=n;i++) for(j=1;j<=n;j++) for(k=1;k<=n;k++) C[i][j]=(C[i][j]+B[i][k]*A[k][j+n])%mod;
for(i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
ans+=dfs1(i);
}
if(ans<n)
{
printf("NIE");
return 0;
}
printf("TAK\n");
for(i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
dfs2(i,i);
}
for(i=1;i<=n;i++) printf("%d\n",to[i]);
return 0;
}
【BZOJ3168】[Heoi2013]钙铁锌硒维生素 高斯消元求矩阵的逆+匈牙利算法的更多相关文章
- HDU4870_Rating_双号从零单排_高斯消元求期望
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4870 原题: Rating Time Limit: 10000/5000 MS (Java/Other ...
- HDU 5833 (2016大学生网络预选赛) Zhu and 772002(高斯消元求齐次方程的秩)
网络预选赛的题目……比赛的时候没有做上,确实是没啥思路,只知道肯定是整数分解,然后乘起来素数的幂肯定是偶数,然后就不知道该怎么办了… 最后题目要求输出方案数,首先根据题目应该能写出如下齐次方程(从别人 ...
- 【BZOJ2137】submultiple 高斯消元求伯努利数
[BZOJ2137]submultiple Description 设函数g(N)表示N的约数个数.现在给出一个数M,求出所有M的约数x的g(x)的K次方和. Input 第一行输入N,K.N表示M由 ...
- SPOJ HIGH(生成树计数,高斯消元求行列式)
HIGH - Highways no tags In some countries building highways takes a lot of time... Maybe that's bec ...
- 【bzoj2115】[Wc2011] Xor DFS树+高斯消元求线性基
题目描述 输入 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图 ...
- 【bzoj3105】[cqoi2013]新Nim游戏 高斯消元求线性基
题目描述 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从 ...
- 【bzoj4004】[JLOI2015]装备购买 贪心+高斯消元求线性基
题目描述 脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装备有 m 个属性,用向量zi(aj ,.....,am) 表示 (1 <= i <= n; 1 <= j < ...
- 【bzoj4269】再见Xor 高斯消元求线性基
题目描述 给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值. 输入 第一行一个正整数N. 接下来一行N个非负整数. 输出 一行,包含两 ...
- hdu 4870 rating(高斯消元求期望)
Rating Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
随机推荐
- 在linux下玩转usb摄像头
硬件平台:PC机一台 .usb摄像头 操作系统:Linux3.0.8 交叉编译环境:arm-none-Linux-gnueabi-gcc 4.5.1 调试步骤: 一.linux 内核解压 1.1使用 ...
- django xadmin的使用和改造
django本身自带一个强大的admin后台管理系统,但是管理起来并不是很方便.这里介绍下xadmin,xadmin是基于bootstrap和admin的一个更强大的后台管理系统 github地址ht ...
- ES6里的修饰器Decorator
修饰器(Decorator)是一个函数,用来修改类的行为. 一.概述 ES6 引入了这项功能,目前 Babel 转码器已经支持Decorator 首先,安装babel-core和babel-plugi ...
- [转]解决Docker容器时间与主机不一致问题
原文: https://blog.csdn.net/luckystar689/article/details/76572046 https://stackoverflow.com/questions/ ...
- 关于批量插入数据之我见(100万级别的数据,mysql)
因前段时间去面试,问到怎样高效向数据库插入10万条记录,之前没处理过类似问题.也没看过相关资料,结果没答上来,今天就查了些资料.总结出三种方法: 測试数据库为mysql!!! 方法一: public ...
- 系统重装 Windows_VHD_辅助处理工具说明文档2
创建一个原始安装的VHD文件 如果采用原始安装的方式,则在WIN7的原始光盘中将install.wim这个文件提取到一个文件夹中备用.如果采用Ghost安装的方式,则将Ghost备份文件提取出来(.G ...
- dev_queue_xmit()函数返回值问题
函数 dev_queue_xmit()用于直接使用sk_buf发包,此函数有返回值,但是并不能通过 此函数返回值为0来说明包已经发送出去且可以立刻释放sk_buff内存.因为网卡发包是一个异步的过程 ...
- Mac环境下反编译apk
0,工具汇总 我们反编译apk主要使用下面三个工具 apktool:用于获取资源文件 dex2jar:获取源文件jar包 JD-GUI:反编译源文件jar包查看源码 找这些工具时折腾了我点时间.如今把 ...
- my_interface
import flask,osserver=flask.Flask(__name__) #当前这个python文件,当做一个服务 @server.route('/error',methods=['ge ...
- select * from A.B.C.D sqlserver 中 select * from .Literary_PuDong.dbo.Users
服务器名.数据库名.表拥有者(架构名).表名 服务器名(服务器IP).数据库名.表拥有者.表名 [192.168.99.66].TEST.dbo.table1[Testdb].TEST.dbo.tab ...