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]变换序列(二分图匹配)相关推荐

  1. P1963 [NOI2009]变换序列

    题目描述 不想水字,详见某谷:P1963 [NOI2009]变换序列 solution 其实    的计算就类似于环上的距离. 对于每一个  都可能有两种位置选择:, . 所以把它们分别连边,二分图上 ...

  2. 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 ...

  3. bzoj 1562 [NOI2009]变换序列 二分图

    题面 题目传送门 解法 显然可以构建一个二分图模型 但是要求出字典序最小的解,那么网络流就无能为力了 考虑用匈牙利算法来跑 匈牙利算法就是用大的来代替小的,那我们把连接的点从小到大排序,然后从左边大的 ...

  4. bzoj1562 [NOI2009]变换序列

    bzoj1562 [NOI2009]变换序列 NOI也有SB题系列. 一个\(i\)只有两种可能的\(T_i\) 要求所有\(T_i\)不重复,且字典序坠小. 仔细想一想匈牙利匹配的过程就可以知道:要 ...

  5. bzoj1562[NOI2009] 变换序列

    题目链接:bzoj1562 题目大意: 给出一个序列(0~n-1),这个序列经过某个变换会成为另外一个序列,但是其中的元素不会改变,给出初始序列与变换后的序列每一位上的"距离",求 ...

  6. bzoj1562[NOI2009]变换序列——2016——3——12

    任意门:http://www.lydsy.com/JudgeOnline/problem.php?id=1562 题目: 对于0,1,-,N-1的N个整数,给定一个距离序列D0,D1,-,DN-1,定 ...

  7. 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 ...

  8. [NOI2009] 变换序列 (匈牙利最大匹配)

    description - solution 我竟然一眼题!! 变换后的TTT数组是[0,n)[0,n)[0,n)的排列,变换规则也有,距离DDD也知道 很明显可以求出iii的可能变换对象 这不就是个 ...

  9. 【二分图匹配】BZOJ1562-[NOI2009] 变换序列

    [题目大意] 对于0,1,-,N-1的N个整数,给定一个距离序列D0,D1,-,DN-1,定义一个变换序列T0,T1,-,TN-1使得每个i,Ti的环上距离等于Di.一个合法的变换序列应是0,1,-, ...

  10. Dinic二分图匹配 || Luogu P3386

    题面:[模板]二分图匹配 思路:Dinic实现二分图匹配,要建一个超级源点(S)和超级汇点(T),分别定为N+M+1和N+M+2 然后S去和N中的数建正边和反边,正边权值为1,反边权值为0:M中的数去 ...

最新文章

  1. 各bert 模型下载
  2. android studio 的中文网站
  3. win7上安装theano keras深度学习框架
  4. 【异常】 ‘ascii‘ codec can‘t decode byte 0xe8 in position 2: ordinal not in range(128)
  5. 低头族的第三只眼,“赛博朋克”新装备让你走路不再撞树
  6. Eclipse调试Logcat类的说明
  7. 第46讲:遇到动态页面怎么办?详解渲染页面爬取
  8. android小程序:计算圆面积
  9. c++ 一个函数包括多个返回值判断_整活函数式编程
  10. 手机5g什么时候普及_5G手机什么时间普及,现在买4G手机划算吗?
  11. 工作占用了太多私人时间_当公司老板过多占用你的个人时间,虽然不是什么大事但很想辞职怎么办?...
  12. 百度导航怎么不显示服务器,百度地图的导航设置中选择在线优先还是离线优先?...
  13. win32.mak下载地址github
  14. 后缀自动机(知识整理+板子总结)
  15. Python:利用matplotlib库绘制统计图(饼图、直方图、散点图、极坐标图和网格图)
  16. 【IDEA】IDEA常用配置
  17. Hamster Farm
  18. python文档学习
  19. Telegram-“只能给双向联系人发送消息”的错误信息
  20. ORACLE按照拼音,部首,笔画排序

热门文章

  1. 【渝粤教育】国家开放大学2019年春季 2083信息技术与教育技术(2) 参考试题
  2. [渝粤教育] 西南科技大学 铁路交通信号控制 在线考试复习资料
  3. 【sklearn第二十五讲】交叉验证
  4. c编程技巧——获取可用的处理器(CPU)核数
  5. Java 实现--时间片轮转 RR 进程调度算法
  6. 36.Linux驱动调试-根据oops定位错误代码行
  7. null value in entry: destinationDir=null
  8. C++详解new/delete
  9. 【转】OUTLOOK签名档中加入写信日期
  10. redis底层数据结构--简单动态字符串 链表 字典 跳跃表 整数集合 压缩列表