标签:line 最大匹配 script href hint mit des 更改 最大
30%的数据中N≤50;
60%的数据中N≤500;
100%的数据中N≤10000。
思路{
容易想到,问题的答案就是i和d(i,T)所限制的点连边做最大匹配,
问题是怎么保证字典序呢?
然后发现如果从后开始做匈牙利的话根据匈牙利的思想(
能上就上,否则创造机会上.若能匹配表示匹配当前字典序最大,
否则为了满足当前字典序更改后面的节点的匹配状况)是能够满足的.
直接上匈牙利就可以了.
}
#include<bits/stdc++.h>
#define LL long long
#define RG register
#define il inline
#define N 100010
using namespace std;
int n,d[N],BL[N],Ans[N];bool used[N];
int dd(int x,int y){return min(n-abs(x-y),abs(x-y));}
struct ed{int nxt,to;}e[N*2];
int head[N],tot;
void link(int u,int v){e[tot].nxt=head[u];e[tot].to=v;head[u]=tot++;}
bool find(int u){
for(int i=head[u];i!=-1;i=e[i].nxt)
if(!used[e[i].to]){
int v=e[i].to;
used[v]=true;
if((!BL[v])||find(BL[v])){
BL[v]=u;
return true;
}
}return false;
}
int main(){
memset(head,-1,sizeof(head));
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d",&d[i]);
int x=i+d[i],y=i-d[i];
x%=n,y=(y+n)%n;
if(dd(x,i)!=d[i])x=-1;
if(dd(y,i)!=d[i])y=-1;
if(x>y)swap(x,y);
if(y!=-1)link(i,y);
if(x!=-1)link(i,x);
}
for(int i=n-1;i!=-1;i--){
memset(used,0,sizeof(used));
if(find(i)!=1)cout<<"No Answer\n",exit(0);
}for(int i=0;i<n;++i)Ans[BL[i]]=i;
for(int i=0;i<n-1;++i)cout<<Ans[i]<<" ";
cout<<Ans[n-1];
return 0;
}
标签:line 最大匹配 script href hint mit des 更改 最大
原文地址:http://www.cnblogs.com/zzmmm/p/7476556.html