Solution -「CF 1586F」Defender of Childhood Dreams
阿新 • • 發佈:2021-10-20
\(\mathcal{Description}\)
Link.
定義有向圖 \(G=(V,E)\),\(|V|=n\),\(\lang u,v\rang \in E \Leftrightarrow u<v\)。求一個對 \(E\) 的染色 \(f\),使得 \(\not\exist \lang v_1,v_2,\cdots,v_{k+1} \rang, |\{f(v_i,v_{i+1})\mid i\in[1,k]\}|=1\),同時最小化 \(f\) 的值域大小。
\(2\le k<n\le10^3\)。
\(\mathcal{Solution}\)
設 \(f\)
證明 該結論的等價表述是,若 \(f\) 值域大小為 \(c\),則 \(n\le k^c\)。當 \(c=0\) 時顯然成立。接下來對 \(c\) 進行歸納:
任取一個 \(f\) 值域大小為 \(c\) 的,被合法染色的圖 \(G\),並任取某種顏色 \(x\),據此將點集 \(V\) 劃分為 \(V_1,V_2,\cdots,V_t\),使得 \(V_i\) 的匯出子圖中不存在顏色為 \(x\) 的邊。這些點集之間的連邊顏色全部為 \(x\),所以 \(t\le k\)。而僅考慮某個 \(V_i\)
模仿歸納方法得到構造方法:劃分點集,將點集之間的邊染色,而後遞迴處理。複雜度上限為 \(\mathcal O(n^2)\)。
\(\mathcal{Code}\)
/*+Rainybunny+*/ #include <bits/stdc++.h> #define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i ) #define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i ) const int MAXN = 1e3; int n, k, mxc, ans[MAXN + 5][MAXN + 5]; inline void solve( const int l, const int r, const int clr ) { if ( l == r ) return ; if ( clr > mxc ) mxc = clr; int s = ( r - l + k ) / k; for ( int i = l; i <= r; i += s ) { solve( i, std::min( i + s - 1, r ), clr + 1 ); rep ( u, l, i - 1 ) rep ( v, i, std::min( i + s - 1, r ) ) { ans[u][v] = clr; } } } int main() { scanf( "%d %d", &n, &k ); solve( 1, n, 1 ); printf( "%d\n", mxc ); rep ( i, 1, n ) rep ( j, i + 1, n ) printf( "%d ", ans[i][j] ); putchar( '\n' ); return 0; }