BZOJ1562: [NOI2009]变换序列(二分图 匈牙利)
Description

Input

Output

Sample Input
1 1 2 2 1
Sample Output
HINT
30%的数据中N≤50;
60%的数据中N≤500;
100%的数据中N≤10000。
Source
这题是二分图应该不难看出来。
对于原序列中的一个点,对应两个可匹配的点。
关键是怎么保证字典序最小
如果是暴力删边+匈牙利的话是$O(n^3)$的。
这里有两种解决方法:
1.强制让$x$号点连向字典序小的点,对失配的点重新匹配
2.将所有边按照字典序排序,优先选择最小的。
同时在匈牙利的时候从最大的往最小的枚举
这实际上利用了匈牙利“抢” 的思想。
如之前的已经匹配过,那么字典序小的会抢字典序大的匹配。同时又因为每次选的是字典序最小的。因此答案可以保证是最优的。
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
const int INF = 1e9 + , MAXN = 1e5 + ;
using namespace std;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int N;
int a[MAXN];
int match[MAXN], vis[MAXN], cur;
vector<int> v[MAXN];
void AddEdge(int x, int y) {
v[x].push_back(y);
v[y].push_back(x);
}
bool Argue(int x) {
for(int i = ; i < v[x].size(); i++) {
int to = v[x][i];
if(vis[to] == cur) continue;
vis[to] = cur;
if(match[to] == - || Argue(match[to])) {
match[to] = x;
return true;
}
}
return false;
}
void Hug() {
int ans = ;
for(int i = N - ; i >= ; i--) {
cur++;
if(!Argue(i)) {printf("No Answer"); exit();}
}
for(int i = ; i < N; i++) match[match[i + N]] = i;
for(int i = ; i < N; i++) printf("%d ", match[i]);
}
main() {
#ifdef WIN32
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
#endif
memset(match, -, sizeof(match));
N = read();
for(int i = ; i < N; i++) {
int x = read();
AddEdge(i, (i + x) % N + N);
AddEdge(i, (i - x + N) % N + N);
}
for(int i = ; i < N << ; i++) sort(v[i].begin(), v[i].end());
Hug();
}
BZOJ1562: [NOI2009]变换序列(二分图 匈牙利)的更多相关文章
- Luogu P1963 [NOI2009]变换序列(二分图匹配)
P1963 [NOI2009]变换序列 题意 题目描述 对于\(N\)个整数\(0,1, \cdots ,N-1\),一个变换序列\(T\)可以将\(i\)变成\(T_i\),其中\(T_i \in ...
- 【BZOJ1562】【jzyzOJ1730】【COGS409】NOI2009变换序列 二分图匹配
[问题描述] 对于N个整数0, 1, ……, N-1,一个变换序列T可以将i变成Ti,其中 定义x和y之间的距离.给定每个i和Ti之间的距离D(i,Ti), 你需要求出一个满足要求的变换 ...
- bzoj1562[NOI2009]变换序列——2016——3——12
任意门:http://www.lydsy.com/JudgeOnline/problem.php?id=1562 题目: 对于0,1,…,N-1的N个整数,给定一个距离序列D0,D1,…,DN-1,定 ...
- 【bzoj1562】【[NOI2009]变换序列】匈牙利算法的性质利用
(上不了p站我要死了,侵权度娘背锅) Description Input Output Sample Input 5 1 1 2 2 1 Sample Output 1 2 4 0 3 HINT 30 ...
- 【BZOJ1562】[NOI2009] 变换序列(匈牙利算法)
点此看题面 大致题意: 给你一个长度为\(n\)的序列\(D\),让你找到一个字典序最小的\(n\)的排列\(T\),满足\(D_i=min(|T_i-i|,n-|T_i-i|)\). 建图 我想建图 ...
- [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≤ ...
- BZOJ1562——[NOI2009]变换序列
1.题意:题意有些难理解 2.分析:我们发现如果要求判断是否合法的话就so easy了,二分图匹配即可,但是我们发现要求输出字典序最小的,那么我们在匈牙利的时候就倒着枚举,另外邻接表中的边一定要排好序 ...
- BZOJ1562 [NOI2009]变换序列 【KM算法】
题目 输入格式 输出格式 输入样例 5 1 1 2 2 1 输出样例 1 2 4 0 3 提示 30%的数据中N≤50: 60%的数据中N≤500: 100%的数据中N≤10000. 题解 每个位置可 ...
- Bzoj 1562: [NOI2009]变换序列 匈牙利算法,二分图匹配
题目: http://cojs.tk/cogs/problem/problem.php?pid=409 409. [NOI2009]变换序列 ★★☆ 输入文件:transform.in 输出文 ...
随机推荐
- Kudu的架构
不多说,直接上干货! Kudu的架构 1.kudu的 基本框架 Kudu 是用于存储结构化( structured )的表( Table ).表有预定义的带类型的列( Columns ),每张表有一 ...
- Devexpress GridControl使用
//不显示内置的导航条. gc1.UseEmbeddedNavigator = false; //不显示分组的面板 gv1.Opti ...
- 创建Brush对象
在GDI+中,可使用笔刷,以各种个颜色和图像填充图形,GDI+的Brush类本身是一个抽象的类,所以是不能实例化Brush的 但是GDI+的API提供五个类,就扩展了Brush类并提供了具体的实现方式 ...
- wpf 查找父元素、子元素方法
1 /// <summary> 2 /// 根据类型查找子元素 3 /// </summary> 4 /// <typeparam name="T"& ...
- Eclipse jee 3.7常用插件安装手记
最近在折腾Maven,于是想重新配置一个Eclipse环境,插件安装挺折腾人的,尤其天朝的网络,你懂的,伤不起啊,因此特地把正确的过程记录下来,供大家参考,节省时间 1.官网下载eclipse-jee ...
- jeecg3.8popup弹出窗口触发失去焦点事件,引发验证弹窗,影响体验问题的解决办法
在初始化表单的代码中添加以下加粗部分,有几个popup就定义几个标志位,主要是防止第一次失去焦点时候的弹窗(此时还未来得及选择),提交表单的时候还是会正常校验的. //popup触发失去焦点事件,设置 ...
- Python异常处理及元类
一.异常处理 异常是错误发生的信号,一旦程序出错就会产生一个异常,如果该异常没有被应用程序处理,那么该异常就会跑出来,程序的执行也随之终止,也就是说异常就是一个事件,该事件会在程序执行过程中发生,影响 ...
- SASS简介及使用方法
一.什么是Sass Sass (Syntactically Awesome StyleSheets)是css的一个扩展开发工具,它允许你使用变量.条件语句等,使开发更简单可维护.这里是官方文档. 二. ...
- The fool doth think he is wise, but the wise man knows himself to be a fool.
The fool doth think he is wise, but the wise man knows himself to be a fool.愚者总自以为聪明,智者则有自知之明.
- c#和c++的运算符优先级
闲来无聊乱写代码.发现基础的东西有的时候也非常的抽象.不信?那来看看下面这条语句: ; ; j = i = -i++; 如果上述代码是vc++代码,那么输出结果是: i=- j=- 请按任意键继续. ...