[NOI2009]変換シーケンス(ハンガリーの最大一致)

説明

解決

私もその質問をちらっと見ました!
ここに画像の説明を挿入します
変換後のTTT配列は[0、n)[0、n)[ 0 n 順列、変換ルール、距離DDもありますD
は、iiが見つかることは明らかであることも知っています。iの可能な変換オブジェクト。
これは最大の一致ではありませんか?
解決策がないということは、一致の数がnnに到達できないことを意味しますnベールの
最小一致辞書式順序を後ろから使用して、後者の前部をより適切に一致させることができるようにします。

コード

#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