【BZOJ1562】[NOI2009] 变换序列(匈牙利算法)
大致题意: 给你一个长度为\(n\)的序列\(D\),让你找到一个字典序最小的\(n\)的排列\(T\),满足\(D_i=min(|T_i-i|,n-|T_i-i|)\)。
建图
我想建图应该是比较简单的吧。
对于给定的\(D_i\),我们可以发现对应的\(T_i\)实际上只有两种取值:
当\(D_i=|T_i-i|\)时,\(T_i=(i+D_i-1)\%n+1\)。
当\(D_i=n-|T_i-i|\)时,\(T_i=(i-D_i+n-1)\%n+1\)。
因此,将\(i\)向这两种取值各连一条边,然后跑匈牙利算法即可。
关于字典序
等等,题目中貌似还要求字典序最小。
让我们来回顾一下匈牙利算法的核心思想:
\(Excerpt\)
匈牙利算法的核心思想就是让位。
我们再回顾一下,匈牙利算法是如何让位的:
\(Excerpt\)
它的让位,通常都是由已匹配好的点给未匹配的点让位。
好,那么我们现在要让字典序最小,肯定就是尽可能要让编号小的数在前面。
换句话说,就是尽可能让编号大的数给编号小的数让位。
综上所述,我们只要倒着做匈牙利匹配,这样求出来的结果一定是字典序最小的。
代码
#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define uint unsigned int
#define LL long long
#define ull unsigned long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define abs(x) ((x)<0?-(x):(x))
#define INF 1e9
#define Inc(x,y) ((x+=(y))>=MOD&&(x-=MOD))
#define ten(x) (((x)<<3)+((x)<<1))
#define N 10000
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
using namespace std;
int n,ee=0,lnk[N+5];
struct edge
{
int to,nxt;
}e[2*N+5];
class FIO
{
private:
#define Fsize 100000
#define tc() (FinNow==FinEnd&&(FinEnd=(FinNow=Fin)+fread(Fin,1,Fsize,stdin),FinNow==FinEnd)?EOF:*FinNow++)
#define pc(ch) (FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,FoutSize,stdout),Fout[(FoutSize=0)++]=ch))
int f,FoutSize,OutputTop;char ch,Fin[Fsize],*FinNow,*FinEnd,Fout[Fsize],OutputStack[Fsize];
public:
FIO() {FinNow=FinEnd=Fin;}
inline void read(int &x) {x=0,f=1;while(!isdigit(ch=tc())) f=ch^'-'?1:-1;while(x=ten(x)+(ch&15),isdigit(ch=tc()));x*=f;}
inline void read_char(char &x) {while(isspace(x=tc()));}
inline void read_string(string &x) {x="";while(isspace(ch=tc()));while(x+=ch,!isspace(ch=tc())) if(!~ch) return;}
inline void write(int x) {if(!x) return (void)pc('0');if(x<0) pc('-'),x=-x;while(x) OutputStack[++OutputTop]=x%10+48,x/=10;while(OutputTop) pc(OutputStack[OutputTop]),--OutputTop;}
inline void write_char(char x) {pc(x);}
inline void write_string(string x) {register int i,len=x.length();for(i=0;i<len;++i) pc(x[i]);}
inline void end() {fwrite(Fout,1,FoutSize,stdout);}
}F;
class Class_HungarianAlgorithm//匈牙利算法
{
private:
int s[N+5],t[N+5],vis[N+5];
public:
inline bool Match(int x,int Time)
{
for(register int i=lnk[x];i;i=e[i].nxt)
{
if(!(vis[e[i].to]^Time)) continue;
vis[e[i].to]=Time;
if(!s[e[i].to]||Match(s[e[i].to],Time)) return s[e[i].to]=x,true;
}
return false;
}
inline void PrintAns() {register int i;for(i=1;i<=n;++i) t[s[i]]=i-1;for(i=1;i<=n;++i) F.write(t[i]),F.write_char(' ');}
}HungarianAlgorithm;
int main()
{
register int i,x,s1,s2;
for(F.read(n),i=1;i<=n;++i) F.read(x),s1=(i+x-1)%n+1,s2=(i-x+n-1)%n+1,add(i,max(s1,s2)),add(i,min(s1,s2));//建边
for(i=n;i;--i) if(!HungarianAlgorithm.Match(i,i)) return puts("No Answer"),0;//倒着做匈牙利算法,这样的结果一定是字典序最小的
return HungarianAlgorithm.PrintAns(),F.end(),0;
}
【BZOJ1562】[NOI2009] 变换序列(匈牙利算法)的更多相关文章
- Bzoj 1562: [NOI2009]变换序列 匈牙利算法,二分图匹配
题目: http://cojs.tk/cogs/problem/problem.php?pid=409 409. [NOI2009]变换序列 ★★☆ 输入文件:transform.in 输出文 ...
- [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]变换序列——2016——3——12
任意门:http://www.lydsy.com/JudgeOnline/problem.php?id=1562 题目: 对于0,1,…,N-1的N个整数,给定一个距离序列D0,D1,…,DN-1,定 ...
- 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]变换序列 【KM算法】
题目 输入格式 输出格式 输入样例 5 1 1 2 2 1 输出样例 1 2 4 0 3 提示 30%的数据中N≤50: 60%的数据中N≤500: 100%的数据中N≤10000. 题解 每个位置可 ...
- BZOJ1562——[NOI2009]变换序列
1.题意:题意有些难理解 2.分析:我们发现如果要求判断是否合法的话就so easy了,二分图匹配即可,但是我们发现要求输出字典序最小的,那么我们在匈牙利的时候就倒着枚举,另外邻接表中的边一定要排好序 ...
- [Luogu 1963] NOI2009 变换序列
[Luogu 1963] NOI2009 变换序列 先%Dalao's Blog 什么?二分图匹配?这个确定可以建图? 「没有建不成图的图论题,只有你想不出的建模方法.」 建图相当玄学,不过理解大约也 ...
- noi2009变换序列
noi2009变换序列 一.题目 1843 变换序列 2009年NOI全国竞赛 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 题目描述 ...
- Luogu P1963 [NOI2009]变换序列(二分图匹配)
P1963 [NOI2009]变换序列 题意 题目描述 对于\(N\)个整数\(0,1, \cdots ,N-1\),一个变换序列\(T\)可以将\(i\)变成\(T_i\),其中\(T_i \in ...
- BZOJ 1562 [NOI2009] 变换序列
[NOI2009] 变换序列 [题解] 就是有一个序列,每个位置可以填两个数,不可重复,问最小字典序. 显然,可以建一个二分图,判合法就是找完美匹配. 那怎么弄最小字典序呢?有好多种解法,我这里给出了 ...
随机推荐
- 洛谷P1378 油滴扩展
P1378 油滴扩展 题目描述 在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界.必须等一个油滴扩展完 ...
- 15-----float(浮动)
浮动 浮动是css里面布局最多的一个属性,也是很重要的一个属性. float:表示浮动的意思.它有四个值. none: 表示不浮动,默认 left: 表示左浮动 right:表示右浮动 看一个例子: ...
- LeetCode 128 Longest Consecutive Sequence 一个无序整数数组中找到最长连续序列
Given an unsorted array of integers, find the length of the longest consecutive elements sequence.Fo ...
- Murano Weekly Meeting 2015.07.14
会议时间: 2015.07.14 主持人: Kirill Zaitsev, core from Mirantis 会议摘要: 1.periodic nightly builds,然后通过mailin ...
- 【Java】国内maven私服
<mirrors> <mirror> <id>alimaven</id> <name>aliyun maven</name> & ...
- Kotlin基础知识
1. 改进点/基础 //安全判空 val length = text?.length; //类型转换 if (object is Car) { var car = object as Ca } //操 ...
- Spring4.x、SpringMVC和DButils整合
tomcat 8.Spring 4.X.JDK1.8 需要jar包: 1)日志组件:log4j # debug < info < warn < error log4j.rootLog ...
- jquery选择器大全参考
在Dom 编程中我们只能使用有限的函数根据id 或者TagName 获取Dom 对象. 然而在jQuery 中则完全不同,jQuery 提供了异常强大的选择器用来帮助我们获取页面上的对象, 并且将对象 ...
- spring技术小结
1.DI和IOC 依赖注入(Dependency Injection)还是控制反转(Inversion of Conctrol) bean通过依赖注入,注册到spring容器里面.spring容器通过 ...
- spring mvc 注解扫描问题 ,扫描不到controller, use-default-filters="false"
今天搭了个spring mvc项目,怎么也扫描不到controller,最后发现问题在use-default-filters="false"上面,乱copy出的问题 (默认值是tr ...