【NOI2009】Bzoj1562 & Codevs1843 变换序列
2016-09-23 16:23
295 查看
【NOI2009】Bzoj1562&Codevs1843 变换序列
Position:http://www.lydsy.com/JudgeOnline/problem.php?id=1562
List
NOI2009Bzoj1562Codevs1843 变换序列List
Description
Input
Output
Sample Input
Sample Output
HINT
Solution
官方题解莫队
Code
Description
Input
输入文件 transform.in 的第一行包含一个整数 N,表示序列的长度。接下来的一行包含 N 个整数 D i ,其中 D i 表示 i 和 T i 之间的距离。
Output
输出文件为 transform.out。如果至少存在一个满足要求的变换序列 T,则输出文件中包含一行 N 个整数,
表示你计算得到的字典序最小的 T;否则输出”No Answer”(不含引号)。注意:
输出文件中相邻两个数之间用一个空格分开,行末不包含多余空格。
Sample Input
51 1 2 2 1
Sample Output
1 2 4 0 3HINT
30%的数据中 N≤50;60%的数据中 N≤500;
100%的数据中 N≤10000。
Solution
观察题中给的式子,发现每个位置可以填两个数,但只能填一个数,求是否每个位置可以填上一个不重复的0~n-1的数,并保证字典序最小,也就是填在前面的数要尽量小。最小字典序的匈牙利,贪心发现可以倒着来跑匈牙利,保证对于当前位置的数尽量小,替换掉的是后面的数,后面的数也保证了尽量小。而正着来后面的数可能会替换掉之前的数,不满足字典序最小。
官方题解%莫队
Transform解题报告湖南省长郡中学 莫涛
【题目大意】
给定n和{Ti},求一个字典序最小的0..n-1的排列{Pi},使{Pi}满足{,或指出无解。
n<=10000。
【解法分析】
不难看出,所给限制即i与Pi的环上距离为Ti,故对于任意i,至多存在两个Pi(从i顺时针或逆时针移动Ti距离)满足限制。
构建二分图模型,以0,1..n-1为X节点,0,1..n-1为Y节点,若Pi=j满足限制则由X的i节点向Y的j节点连一条边,则问题转化为判断是否存在完备匹配,若存在则求出字典序最小的匹配方案。
【算法一】
首先使用匈牙利算法求解,若不存在完备匹配则返回无解,否则按如下流程调整使得求得字典序最小解:
for do
·if i与ai,bi(ai>bi)有边且i与ai匹配 then
·删去匹配边(i,ai)并暂时禁用该边
·令j为原来与bi匹配的点
·将i与bi匹配
·if 从j出发可以找到增广路 then
·保留该次增广,并在以后的增广中禁止改变匹配边(i,bi)
·else 还原上述改动
该算法的核心思想即利用字典序比较的特性,从前往后尝试改小每一位,若更改后剩余部分存在可行解则永久保留该次更改,否则撤销。
由于每个点至多有两条出边,故只在取了匹配了编号较大的点时尝试匹配编号较小的点,而剩下部分有可行解的条件为存在完备匹配,若直接用匈牙利算法求解则时间复杂度为O(n^3),但我们知道:
对于任意残量网络,使用增广路算法均可求得最大流(最大匹配)。
而对于任意k(k>i),k均已匹配,故只需从i出发寻找增广路即可,这样时间复杂度就是O(n^2)了,可以通过测试数据。
【算法二】
考虑到该图非常特殊(X节点出度至多为2),可以从图论的角度求解。
首先,如果存在度为1的点,那么可以直接确定匹配,故可以使用队列持续删去度为1的点及其确定的匹配点及于它们相关的边,直到不存在度为1的点。
然后,如果此时存在度为0的解,那么可以直接返回无解。
最后,由于所有的X节点度大于1且不大于2,故度均为2;而所有Y节点度大于1且∑d(X)=∑d(Y),故所有Y节点度均为2。
一个所有点度均为2的图必然是若干不相交的环。而一个环中只存在两种匹配方案,直接选择较小者即可。
该算法时间复杂度仅为O(n)。
【算法三】
算法二虽然优秀但实现较繁琐,不妨将其与算法一结合起来。
考虑直接使用二分图匹配,对于算法二种在第一步删去的点,必然能求出正确的匹配,解不优只会发生在环中。尝试改进匹配算法:
从大到小增广点i,寻找增广路时优先走向编号较小的点。
证明:
1.对于任一环,匹配的最后结果由最后增广的点决定,由上述算法的特性知,一定会找到该环内的最优解。
2.对于环外一点,若存在经过该环的增广路,则该环内某X节点存在连向环外的边,那么它的度数超过2,矛盾,故不会因为环外某点的增广使得该环的匹配方案改变。
虽然该算法时间复杂度为O(n^2),但思维复杂度与编程复杂度均很低,不失为考场上的好算法。
【小结】
算法一具有普适性,其核心思想也广泛应用于求字典序最小方案的各种问题中;算法二充分挖掘了本题中图的特殊性,时间复杂度达到理论下界;算法三主要利用了贪心思想,非常简洁,但其证明却不是那么显然。
值得一提的是,算法三的正确性是基于该图的特殊性的,因而缺少可推广性,即不能解决一般二分图的字典序最小的匹配,下图即一个反例:
使用算法三将求出(1,1)(2,3)(3,2),而最优解显然是(1,1)(2,2)(3,3)。
此外,本题还可以利用2-SAT模型求解,但该模型在各方面均不优于二分图模型,故略去不提。
Code
// <transform.cpp> - Fri Sep 23 08:09:06 2016 // This file is made by YJinpeng,created by XuYike's black technology automatically. // Copyright (C) 2016 ChangJun High School, Inc. // I don't know what this program is. #include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #define MOD 1000000007 #define INF 1e9 using namespace std; typedef long long LL; const int MAXN=100010; const int MAXM=100010; inline int max(int &x,int &y) {return x>y?x:y;} inline int min(int &x,int &y) {return x<y?x:y;} inline int gi() { register int w=0,q=0;register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')q=1,ch=getchar(); while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar(); return q?-w:w; } int n,k,t[5],match[MAXN]; vector<int>b[MAXN];bool f[MAXN]; void work(int i,int a){ int b=i+a; if(b<n)t[++k]=n+b;b=i-a; if(b>=0)t[++k]=n+b; } inline void add(int v,int u){ b[u].push_back(v);b[v].push_back(u); } inline bool dfs(register int x){ if(f[x])return 0; int num=b[x].size();f[x]=true; for(int i=0;i<num;i++){ int nex=b[x][i]; if(match[nex]==-1||dfs(match[nex])){ match[x]=nex;match[nex]=x;f[x]=0;return 1; } }f[x]=0; return 0; } void pri(){printf("No Answer");exit(0);} int main() { freopen("transform.in","r",stdin); freopen("transform.out","w",stdout); n=gi(); for(int i=0;i<n;i++){ k=0;int a=gi();work(i,a); work(i,n-a); sort(t+1,t+1+k);for(int o=1;o<=k;o++)add(i,t[o]); } for(int i=0;i<MAXN;i++)match[i]=-1; for(int i=n-1;i>=0;i--) if(match[i]==-1)if(!dfs(i))pri(); for(int i=0;i<n-1;i++)printf("%d ",match[i]-n); printf("%d",match[n-1]-n); return 0; }
相关文章推荐
- BZOJ3275 Number (最小割)
- BZOJ2809——[Apio2012]dispatching
- BZOJ2809——[Apio2012]dispatching
- 最长回文子串(转载自网易博客:鼻子很帅的猪)
- 信息竞赛学习笔记:POJ3579中位数(二分)
- bzoj1088[SCOI2005]扫雷
- bzoj1086[SCOI2005]王室联邦
- [BZOJ1087][SCOI2005]互不侵犯King(状压)[第二题]
- BZOJ 1502 NOI 2005 月下柠檬树
- [bzoj1003] [ZJOI2006]物流运输trans
- [bzoj1500][NOI2005]维修数列
- [bzoj1208] [HNOI2004]宠物收养所
- [bzoj1269][AHOI2006]文本编辑器editort
- [bzoj1503][NOI2004]郁闷的出纳员
- bzoj4305 数学
- bzoj3926 广义后缀自动机
- bzoj2780 广义后缀自动机+parent树+Dfs序+树状数组
- BZOJ1997 2-sat
- bzoj4027 贪心
- [BZOJ2038][2009国家集训队][莫队][分块]小z的袜子