[NOI2009] 变换序列 (匈牙利最大匹配)

description

solution

我竟然一眼题!!
在这里插入图片描述
变换后的 T T T数组是 [ 0 , n ) [0,n) [0,n)的排列,变换规则也有,距离 D D D也知道
很明显可以求出 i i i的可能变换对象
这不就是个最大匹配??
无解就是匹配数量达不到 n n n罢了
最小字典序那就从后往前匹配,这样前面的就可以让后面的让出更优匹配

code

#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
#define maxn 10005
vector < int > G[maxn];
int n;
bool vis[maxn];
int match[maxn], link[maxn];

bool find( int u ) {
    
    
	for( int i = 0;i < G[i].size();i ++ ) {
    
    
		int v = G[u][i];
		if( vis[v] ) continue;
		vis[v] = 1;
		if( ! match[v] || find( match[v] ) ) {
    
    
			match[v] = u;
			link[u] = v;
			return 1;
		}
	}
	return 0;
}

int main() {
    
    
	scanf( "%d", &n );
	for( int i = 0, d;i < n;i ++ ) {
    
    
		scanf( "%d", &d );
		int x = ( i + d ) % n;
		int y = ( i - d + n ) % n;
		G[i].push_back( min( x, y ) );
		G[i].push_back( max( x, y ) );
	}
	int ans = 0;
	for( int i = n - 1;~ i;i -- ) {
    
    
		memset( vis, 0, sizeof( vis ) );
		if( find( i ) ) ans ++;
	}
	if( ans != n ) return ! printf( "No Answer\n" );
	for( int i = 0;i < n;i ++ )
		printf( "%d ", link[i] );
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Emm_Titan/article/details/113702999