Luogu P1963 [NOI2009]变换序列(二分图匹配)
P1963 [NOI2009]变换序列
题意
题目描述
对于\(N\)个整数\(0,1, \cdots ,N-1\),一个变换序列\(T\)可以将\(i\)变成\(T_i\),其中\(T_i \in \{ 0,1,\cdots, N-1\}\)且\(\bigcup_{i=0}^{N-1} \{T_i \} = \{0,1,\cdots,N-1 \}\),\(\forall x,y \in \{0,1,\cdots , N-1\}\),定义\(x\)和\(y\)之间的距离\(D(x,y)=min\{|x-y|,N-|x-y|\}\)。给定每个\(i\)和\(T_i\)之间的距离\(D(i,T_i)\),你需要求出一个满足要求的变换序列\(T\)。如果有多个满足条件的序列,输出其中字典序最小的一个。
说明:对于两个变换序列\(S\)和\(T\),如果存在\(p<N\),满足对于\(i=0,1,\cdots p-1\),\(S_i=T_i\)且\(S_p<T_p\),我们称\(S\)比\(T\)字典序小。
输入输出格式
输入格式:
第一行包含一个整数\(N\),表示序列的长度。接下来的一行包含\(N\)个整数\(D_i\),其中\(D_i\)表示\(i\)和\(T_i\)之间的距离。
输出格式:
如果至少存在一个满足要求的变换序列\(T\),则输出文件中包含一行\(N\)个整数,表示你计算得到的字典序最小的\(T\);否则输出No Answer
。注意:输出文件中相邻两个数之间用一个空格分开,行末不包含多余空格。
输入输出样例
输入样例:
5
1 1 2 2 1
输出样例:
1 2 4 0 3
说明
对于\(30 \%\)的数据,满足:\(N \leq 50\);
对于\(60 \%\)的数据,满足:\(N \leq 500\);
对于\(100 \%\)的数据,满足:\(N \leq 10000\)。
思路
这题\(5 \ mins\)之内做不出来我吃屎。 --Uranus
...
时间到了,记得你打的赌啊。 --oyyz
这个故事告诉我们不要随便插\(flag\)。
进入正题。对于每一个\(i\),显然有两个\(T_i\)可以满足\(D(i,T_i)=D_i\),即:
\[T_i=i+D_i \ ( \mod n) \ or \ T_i=i-D_i \ ( \mod n)\]
题目询问的就是是否有一个序列\(T\)能满足上述要求且\(T\)为\(0-(n-1)\)的一个排列。那么我们就可以用二分图匹配的方法来对\(i\)尽可能匹配\(T_i\),从而得到是否有解。
那么如何让解满足字典序最小呢?想想二分图匹配中匈牙利算法的过程:尽量满足后匈牙利的点能够满足匹配,将前面匹配过的点向后移。我们就可以利用这个思路,反向匹配,那么就能达到字典序最优。
AC代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e4+514;
int n,to[MAXN][2],match[MAXN],inv[MAXN];
bool vis[MAXN];
int read()
{int re=0;char ch=getchar();while(!isdigit(ch)) ch=getchar();while(isdigit(ch)) re=(re<<3)+(re<<1)+ch-'0',ch=getchar();return re;
}
bool dfs(int now)
{for(int i=0;i<2;i++){int hjj=to[now][i];if(!vis[hjj]){vis[hjj]=true;if(match[hjj]==-1||dfs(match[hjj])){match[hjj]=now,inv[now]=hjj;return true;}}}return false;
}
int main()
{n=read();memset(match,-1,sizeof match);for(int i=0;i<n;i++){int x=read();to[i][0]=(i+x)%n,to[i][1]=(i-x+n)%n;if(to[i][0]>to[i][1]) swap(to[i][0],to[i][1]);}for(int i=n-1;i>=0;i--){memset(vis,false,sizeof vis);if(!dfs(i)){printf("No Answer");return 0;}}for(int i=0;i<n;i++) printf("%d ",inv[i]);return 0;
}
转载于:https://www.cnblogs.com/coder-Uranus/p/9759982.html
Luogu P1963 [NOI2009]变换序列(二分图匹配)相关推荐
- P1963 [NOI2009]变换序列
题目描述 不想水字,详见某谷:P1963 [NOI2009]变换序列 solution 其实 的计算就类似于环上的距离. 对于每一个 都可能有两种位置选择:, . 所以把它们分别连边,二分图上 ...
- BZOJ1562: [NOI2009]变换序列(二分图 匈牙利)
Description Input Output Sample Input 5 1 1 2 2 1 Sample Output 1 2 4 0 3 HINT 30%的数据中N≤50: 60%的数据中N ...
- bzoj 1562 [NOI2009]变换序列 二分图
题面 题目传送门 解法 显然可以构建一个二分图模型 但是要求出字典序最小的解,那么网络流就无能为力了 考虑用匈牙利算法来跑 匈牙利算法就是用大的来代替小的,那我们把连接的点从小到大排序,然后从左边大的 ...
- bzoj1562 [NOI2009]变换序列
bzoj1562 [NOI2009]变换序列 NOI也有SB题系列. 一个\(i\)只有两种可能的\(T_i\) 要求所有\(T_i\)不重复,且字典序坠小. 仔细想一想匈牙利匹配的过程就可以知道:要 ...
- bzoj1562[NOI2009] 变换序列
题目链接:bzoj1562 题目大意: 给出一个序列(0~n-1),这个序列经过某个变换会成为另外一个序列,但是其中的元素不会改变,给出初始序列与变换后的序列每一位上的"距离",求 ...
- bzoj1562[NOI2009]变换序列——2016——3——12
任意门:http://www.lydsy.com/JudgeOnline/problem.php?id=1562 题目: 对于0,1,-,N-1的N个整数,给定一个距离序列D0,D1,-,DN-1,定 ...
- 1562. [NOI2009]变换序列【二分图】
Description Input Output Sample Input 5 1 1 2 2 1 Sample Output 1 2 4 0 3 HINT 30%的数据中N≤50: 60%的数据中N ...
- [NOI2009] 变换序列 (匈牙利最大匹配)
description - solution 我竟然一眼题!! 变换后的TTT数组是[0,n)[0,n)[0,n)的排列,变换规则也有,距离DDD也知道 很明显可以求出iii的可能变换对象 这不就是个 ...
- 【二分图匹配】BZOJ1562-[NOI2009] 变换序列
[题目大意] 对于0,1,-,N-1的N个整数,给定一个距离序列D0,D1,-,DN-1,定义一个变换序列T0,T1,-,TN-1使得每个i,Ti的环上距离等于Di.一个合法的变换序列应是0,1,-, ...
- Dinic二分图匹配 || Luogu P3386
题面:[模板]二分图匹配 思路:Dinic实现二分图匹配,要建一个超级源点(S)和超级汇点(T),分别定为N+M+1和N+M+2 然后S去和N中的数建正边和反边,正边权值为1,反边权值为0:M中的数去 ...
最新文章
- 各bert 模型下载
- android studio 的中文网站
- win7上安装theano keras深度学习框架
- 【异常】 ‘ascii‘ codec can‘t decode byte 0xe8 in position 2: ordinal not in range(128)
- 低头族的第三只眼,“赛博朋克”新装备让你走路不再撞树
- Eclipse调试Logcat类的说明
- 第46讲:遇到动态页面怎么办?详解渲染页面爬取
- android小程序:计算圆面积
- c++ 一个函数包括多个返回值判断_整活函数式编程
- 手机5g什么时候普及_5G手机什么时间普及,现在买4G手机划算吗?
- 工作占用了太多私人时间_当公司老板过多占用你的个人时间,虽然不是什么大事但很想辞职怎么办?...
- 百度导航怎么不显示服务器,百度地图的导航设置中选择在线优先还是离线优先?...
- win32.mak下载地址github
- 后缀自动机(知识整理+板子总结)
- Python:利用matplotlib库绘制统计图(饼图、直方图、散点图、极坐标图和网格图)
- 【IDEA】IDEA常用配置
- Hamster Farm
- python文档学习
- Telegram-“只能给双向联系人发送消息”的错误信息
- ORACLE按照拼音,部首,笔画排序
热门文章
- 【渝粤教育】国家开放大学2019年春季 2083信息技术与教育技术(2) 参考试题
- [渝粤教育] 西南科技大学 铁路交通信号控制 在线考试复习资料
- 【sklearn第二十五讲】交叉验证
- c编程技巧——获取可用的处理器(CPU)核数
- Java 实现--时间片轮转 RR 进程调度算法
- 36.Linux驱动调试-根据oops定位错误代码行
- null value in entry: destinationDir=null
- C++详解new/delete
- 【转】OUTLOOK签名档中加入写信日期
- redis底层数据结构--简单动态字符串 链表 字典 跳跃表 整数集合 压缩列表