bzoj1562: [NOI2009]变换序列
二分图匹配求最小字典序。从后面往前搞就可以了。然后因为我邻接表的写法不能add(i,v)再add(i,d)!!!注意邻接表的顺序
#include<cstdio> #include<cstring> #include<cctype> #include<algorithm> #include<bitset> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define clr(x,c) memset(x,c,sizeof(x)) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=1e4+5; struct edge{ int to;edge *next; }; edge es[nmax<<1],*pt=es,*head[nmax]; void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++; } bitset<nmax>vis; int ans[nmax],match[nmax]; bool dfs(int x){ qwq(x) if(!vis[o->to]){ vis[o->to]=1; if(!match[o->to]||dfs(match[o->to])){ ans[x]=o->to;match[o->to]=x; return 1; } } return 0; } int main(){ int n=read(),u,v,d; rep(i,1,n) { u=read();v=i+u-1;d=i-1-u; if(v>=n) v-=n;if(d<0) d+=n; if(v>d) swap(v,d);add(i,d);add(i,v); } dwn(i,n,1){ vis.reset(); if(!dfs(i)) { puts("No Answer");return 0; } } rep(i,1,n-1) printf("%d ",ans[i]);printf("%d",ans[n]); return 0; }
1562: [NOI2009]变换序列
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1717 Solved: 871
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
5
1 1 2 2 1
1 1 2 2 1
Sample Output
1 2 4 0 3
HINT
30%的数据中N≤50;
60%的数据中N≤500;
100%的数据中N≤10000。