P1963 [NOI2009] 变换序列
求最小字典序
匈牙利算法进行匹配
因为每一次是要求已经匹配好的人进行换对象
如果从前面开始,那就是会要求前面已经匹配好的人换对象,答案就不一定是字符串最小
而如果从后面开始,那就是要求后面已经匹配好的人换对象,一定可以保证局部字典序最小
//选择字典序最小的就可以了
//最多和两个点进行匹配
#include <bits/stdc++.h>
using namespace std;
const int N=10005;
const int M=2*N;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
int g[N][2];
int vis[N],match[N];
int ans[N];
bool dfs(int now,int dep) {
for(int i=0;i<2;i++) {
int to=g[now][i];
if(vis[to]==dep)continue;
vis[to]=dep;
if(match[to]==-1||dfs(match[to],dep)) {
match[to]=now;
ans[now]=to;
return 1;
}
}
return 0;
}
int main() {
memset(match,-1,sizeof(match));
memset(vis,-1,sizeof(vis));
int n=read();
for(int i=0;i<n;i++) {
int x=read();
int t1=(i+x)%n,t2=(i-x+n)%n;
if(t1>t2)swap(t1,t2);
g[i][0]=t1;
g[i][1]=t2;
}
for(int i=n-1;i>=0;i--)
if(dfs(i,i)==0)return cout<<"No Answer",0;
for(int i=0;i<n;i++)cout<<ans[i]<<' ';
return 0;
}
//逆向思维进行贪心就可以了
//从后面开始就是对的
//有的时候求字典序最小或者说其他东西最小,往往只需要把某些东西调换一下子就可以了
标签:ch,匹配,int,NOI2009,序列,P1963,字典
From: https://www.cnblogs.com/basicecho/p/16945037.html