P4100 [HEOI2013]钙铁锌硒维生素

题目描述

银河队选手名单出来了!小林,作为特聘的营养师,将负责银河队选手参加 宇宙比赛的饮食。

众所周知,前往宇宙的某个星球,通常要花费好长好长的时间,人体情况在 这之间会发生变化,因此,需要根据每天的情况搭配伙食,来保证营养。

小林把人体需要的营养分成了 \(n\) 种,这些营养包括但不限于铁,钙。他准备 了 \(2\) 套厨师机器人,一套厨师机器人有 \(n\) 个,每个厨师机器人只会做一道菜,这道菜一斤能提供第 \(i\) 种营养 \(x_i\) 微克。想要吃这道菜的时候,只要输入一个数,就能吃到对应数量的这道菜了。为防止摄入过量对身体造成的伤害,每个机器人还 有防过量摄入药,只要输入一个数,就能生成一定剂量的药,吃了这些药,就能减少相当于食用对应数目的这道菜提供的营养。

小林之所以准备 \(2\) 套厨师机器人,正是因为旅途漫漫,难以预计,也许某一 个厨师机器人在途中坏掉,要是影响了银河队选手的身体,就不好了。因此,第 \(2\) 套厨师机器人被用来做第 \(1\) 套的备用。小林需要为每一个第 \(1\) 套厨师机器人选 一个第 \(2\) 套厨师机器人作备份,使得当这个机器人坏掉时,用备份顶替,整套厨 师机器人仍然能搭配出任何营养需求,而且,每个第 \(2\) 套厨师机器人只能当一个 第 \(1\) 套厨师机器人的备份。

输入输出格式

输入格式:

输入文件的第一行包含一个正整数 \(n\)。

接下来 \(n\) 行,每行 \(n\) 个整数,表示第 \(1\) 套厨师机器人做的菜每一斤提供的每种营养。

再接下来 \(n\) 行,每行 \(n\) 个整数, 表示第 \(2\) 套厨师机器人做的菜每一斤提供的每种营养。

输出格式:

输出文件的第一行是一个字符串,如果无法完成任务,输出“\(NIE\)”,否则输 出“\(TAK\)”,并跟着 \(n\) 行,第 \(i\) 行表示第 \(i\) 个第 \(1\) 套机器人的备份是哪一个第 \(2\) 套机器人。为了避免麻烦,如果有多种可能的答案,请给出字典序最小的那一组。

说明

对于\(10\%\)的数据,\(n = 2\);

对于\(20\%\)的数据,\(n ≤ 10\);

对于\(40\%\)的数据,\(n ≤ 30\);

对于\(60\%\)的数据,\(n ≤ 50\);

对于\(80\%\)的数据,\(n ≤ 100\);

对于\(100\%\)的数据,\(1 ≤ n ≤ 300\),所有出现的整数均非负,且不超过 \(10,000\)。


好题阿

首先\(n\)个\(A\)向量得是向量无关的

然后每个\(B\)向量一定可以被\(A\)向量作为基底表示出来,即\(B=\sum c_iA_i\),若\(c_i\)不为\(0\),就说明这个\(B\)必须要\(A_i\)才能被表示,说明去掉这个\(A_i\)后\(B\)与其他\(A\)线性无关,即可以换掉这个\(A\)。

那么\(C*A=B\),矩阵求个逆把\(C\)搞出来,我们就可以确定替换关系,然后进行二分图匹配。

这时候不一定字典序最小,我们再随便跑跑匹配改一改跑一个最小就可以了。


Code:

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
const int mod=998244353;
const int N=602;
inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
#define mul(x,y) (1ll*(x)*(y)%mod)
int qp(int d,int k){int f=1;while(k){if(k&1)f=mul(f,d);d=mul(d,d),k>>=1;}return f;}
int read()
{
int x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x;
}
int a[N][N],b[N][N],yuu[N][N],yuy[N][N],n;
bool Matrixinv()
{
for(int i=1;i<=n;i++) a[i][i+n]=1;
for(int i=1;i<=n;i++)
{
int id=-1;
for(int j=i;j<=n;j++) if(a[j][i]) {id=j;break;}
if(id==-1) return false;
std::swap(a[i],a[id]);
int inv=qp(a[i][i],mod-2);
for(int j=n<<1;j>=i;j--) a[i][j]=mul(a[i][j],inv);
for(int j=i+1;j<=n;j++)
for(int k=n<<1;k>=i;k--)
a[j][k]=add(a[j][k],mod-mul(a[j][i],a[i][k]));
}
for(int i=n;i;i--)
for(int j=i-1;j;j--)
for(int k=n<<1;k>=i;k--)
a[j][k]=add(a[j][k],mod-mul(a[j][i],a[i][k]));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=a[i][j+n];
return true;
}
int used[N],mat[N],to[N],ban[N];
bool dfs(int now)
{
for(int i=1;i<=n;i++)
if(yuy[now][i]&&!used[i]&&!ban[i])
{
used[i]=1;
if(!mat[i]||dfs(mat[i]))
{
mat[i]=now;
to[now]=i;
return true;
}
}
return false;
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
b[i][j]=read();
if(!Matrixinv()) return puts("NIE"),0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
yuu[i][j]=add(yuu[i][j],mul(b[i][k],a[k][j]));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(yuu[i][j])
yuy[j][i]=1;
for(int i=1;i<=n;i++)
{
memset(used,0,sizeof used);
if(!dfs(i)) return puts("NIE"),0;
}
puts("TAK");
int tto[N],tmat[N];
for(int i=1;i<=n;i++)
{
memset(used,0,sizeof used);
for(int j=1;j<=n;j++) tto[j]=to[j],tmat[j]=mat[j];
int bee=to[i],flag=0;mat[bee]=0;
for(int j=1;j<bee;j++)
if(yuy[i][j]&&!ban[j]&&!used[j])
{
used[j]=1;
if(!ban[j]&&dfs(mat[j]))
{
to[i]=j,mat[j]=i;
flag=1;break;
}
}
if(!flag) for(int j=1;j<=n;j++) to[j]=tto[j],mat[j]=tmat[j];
ban[to[i]]=1;
}
for(int i=1;i<=n;i++) printf("%d\n",to[i]);
return 0;
}

2019.2.15

洛谷 P4100 [HEOI2013]钙铁锌硒维生素 解题报告的更多相关文章

  1. 洛谷_Cx的故事_解题报告_第四题70

    1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h>   struct node {     long x,y,c; ...

  2. 洛谷 P2317 [HNOI2005]星际贸易 解题报告

    P2317 [HNOI2005]星际贸易 题目描述 输入输出格式 输入格式: 输出格式: 如果可以找到这样的方案,那么输出文件output.txt中包含两个整数X和Y.X表示贸易额,Y表示净利润并且两 ...

  3. 洛谷 P3802 小魔女帕琪 解题报告

    P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...

  4. 洛谷 P2606 [ZJOI2010]排列计数 解题报告

    P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...

  5. 洛谷1303 A*B Problem 解题报告

    洛谷1303 A*B Problem 本题地址:http://www.luogu.org/problem/show?pid=1303 题目描述 求两数的积. 输入输出格式 输入格式: 两个数 输出格式 ...

  6. 洛谷 P3084 [USACO13OPEN]照片Photo 解题报告

    [USACO13OPEN]照片Photo 题目描述 农夫约翰决定给站在一条线上的\(N(1 \le N \le 200,000)\)头奶牛制作一张全家福照片,\(N\)头奶牛编号\(1\)到\(N\) ...

  7. 洛谷 P1379 八数码难题 解题报告

    P1379 八数码难题 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初 ...

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

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

  9. NOIP2015 D2T3 洛谷2680 BZOJ4326 运输计划 解题报告

    前言:个人认为这是历年NOIP中比较简单的最后一题了,因此将自己的思路与大家分享. 题目大意: 给一棵无根树,给出m条路径.允许将树上的一条边的权值改为0.求m条路径长度最大值的最小值.n,m< ...

随机推荐

  1. odoo订餐系统之订单设计

    订餐系统的主要功能便是用户下单部分,这里我们分为表头mylunch_order和表体mylunch_order_line两张主要的数据表,表头主要记录订单的一些通用信息,比如下单的操作人员 下单日期 ...

  2. sql字符串累加

    函数 stuff(param1, startIndex, length, param2) 函数说明将param1中自startIndex(SQL中都是从1开始,而非0)起,删除length个字符,然后 ...

  3. JDK8漫谈——集合更强大

    解决什么问题 集合计算不足 解决重复代码 背后思想 管道 封装 数据处理 内容说明 是什么 计算担当.集合用于数据存储,流用于数据计算,不会修改原始数据 内置循环.高级迭代器,内置循环和计算 单向.数 ...

  4. RabbitMQ 延时消息设计

    问题背景 所谓"延时消息"是指当消息被发送以后,并不想让消费者立即拿到消息,而是等待指定时间后,消费者才拿到这个消息进行消费. 场景一:客户A在十二点下了一个订单,我想半个小时后来 ...

  5. Docker容器学习梳理 - 基础环境安装

    以下是centos系统安装docker的操作记录 1)第一种方法:采用系统自带的docker安装,但是这一般都不是最新版的docker安装epel源[root@docker-server ~]# wg ...

  6. Gitblit版本服务器环境部署记录

    Gitblit介绍Gitblit 是一个纯 Java 库用来管理.查看和处理 Git 资料库.相当于 Git 的 Java 管理工具,支持linux系统.Git是分布式版本控制系统,它强调速度.数据一 ...

  7. Nginx入门【转】

    原文地址:http://blog.csdn.net/u012486840/article/details/53098890 1.静态HTTP服务器 首先,Nginx是一个HTTP服务器,可以将服务器上 ...

  8. 北航学堂Android客户端Beta阶段发布说明

    在从学姐那里拿到服务接口的代码最终连通服务器之后,经过我们团队的努力,终于把前后端融合生成了我们目前的版本, 因为我们在Alpha阶段网络连接部分是一直没有搞定的,所以这个版本其实并不算是真正的Bet ...

  9. Linux内核期末总结

    20135316王剑桥<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC 1000029000 第一周 http://www.cn ...

  10. Linux内核分析第八周总结

    第八章 进程的切换和系统的一般执行过程 进程调度与进程调度的时机分析 第一种分类: I/O密集型(I/O-bound):频繁的进行I/O,通常会花费很多时间等待I/O操作的完成 CPU密集型(CPU- ...