[NOI 2009]変換シーケンス


この問題は9時から読んでいますが...今までずっと書いていますが...
事実は混乱したコードを続けないで、もう一度書いたほうがいいことを証明しています.
まず私は
各点には対応する2つの点しかありませんが、これは明らかに冒頭と後ろの直接的な押し出しを制約しているのではないでしょうか.
では明らかにO(n^2)は通過できるのですが・・・
ポイントごとに最大2つのエッジの二分図であることに気づきました
しかしよく考えていないで、依然としてそれが最初の後ろを制約してすべて押し出したと感じます
すぐに...シミュレーション二分図マッチングを書きました...
そしてwa...
よく考えてみると、MSは現在の状況で制約できる点がない場合があります.例えば、図には2つの連通成分が存在します.だからだめです.
私が書いたプログラムはハンガリーのように拡張路を修正することはできません.so......
二分図マッチングでなければなりませんが...
それから辞書の順序の問題があります.
各点には2つの選択肢しかないので、後ろから暴力を振るうことができます.まず辞書の順序が小さいものを選んで、完全に一致しているかどうかを仮定して、あれば選択できます.
最適化するのは後から前へ行って、先に辞書の順序の小さい拡張路があるかどうかを仮定します
Linuxの下には何かわけのわからない定義がlinkされていますが...一時的にreplaceしてしまいました...
//Lib
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>

#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<set>
#include<map>
#include<list>
using namespace std;
//Macro
#define	rep(i,a,b)	for(int i=a,tt=b;i<=tt;++i)
#define	drep(i,a,b)	for(int i=a,tt=b;i>=tt;--i)
#define	erep(i,e,x)	for(int i=x;i;i=e[i].next)
#define	irep(i,x)	for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
#define	read()	(strtol(ipos,&ipos,10))
#define	sqr(x)	((x)*(x))
#define	pb	push_back
#define	PS	system("pause");
typedef	long long	ll;
typedef	pair<int,int>	pii;
const int oo=~0U>>1;
const double inf=1e100;
const double eps=1e-6;
string name="transform", in=".in", out=".out";
//Var
struct E
{
	int next,node;
}e[40008];
int n,tot,ans;
int s[10008],c[10008],h[20008];
int llink[20008],to[10008][2];
bool vis[20008];
void add(int a,int b)
{
	e[++tot].next=h[a];e[tot].node=b;h[a]=tot;
}
void Init()
{
	scanf("%d",&n);int x,y;
	rep(i,1,n)scanf("%d",s+i);
	rep(i,1,n)
	{
		x=i-s[i];if(x<=0)x+=n;
		y=i+s[i];if(y>n)y-=n;
		to[i][0]=min(x,y);to[i][1]=max(x,y);
		add(i,x+n);if(x!=y)add(i,y+n);
	}
}
bool DFS(int u)
{
	erep(i,e,h[u])
	{
		int v=e[i].node;
		if(vis[v]==0)
		{
			vis[v]=true;
			if(!llink[v]||DFS(llink[v]))
			{
				llink[v]=u;
				llink[u]=v;
				return true;
			}
		}
	}
	return false;
}
void Work()
{
	rep(i,1,n)
	{
		memset(vis,0,sizeof vis);
		if(DFS(i))ans++;
	}
	if(ans<n){printf("No Answer
");return;} int x,y,tmp; drep(i,n,1) { if(to[i][0]+n!=llink[i]) { x=to[i][0];y=to[i][1];tmp=llink[x+n]; memset(vis,0,sizeof vis); vis[x+n]=true;llink[x+n]=i;llink[y+n]=0; if(DFS(tmp))llink[i]=x+n; else llink[x+n]=tmp,llink[y+n]=i; } } rep(i,1,n-1)printf("%d ",llink[i]-n-1); printf("%d
",llink[n]-n-1); } int main() { // freopen((name+in).c_str(),"r",stdin); // freopen((name+out).c_str(),"w",stdout); Init(); Work(); // PS; return 0; }