日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CodeForces1477D Nezzar and Hidden Permutations(构造+调整+菊花图)

發(fā)布時間:2023/12/3 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces1477D Nezzar and Hidden Permutations(构造+调整+菊花图) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

problem

洛谷鏈接

題意:給定 mmm 條形如 (u,v)(u,v)(u,v) 的限制,要求 au,ava_u,a_vau?,av? 的相對大小關系與 bu,bvb_u,b_vbu?,bv? 相同。

且盡可能減少 ai=bia_i=b_iai?=bi? 的數量,輸出 a,ba,ba,b 兩個排列。

solution

我們考慮將每條 (u,v)(u,v)(u,v) 限制轉化成圖 GGG 中的一條邊。

如果某個點 iii 的邊數 =n?1=n-1=n?1,則一定有 ai=bia_i=b_iai?=bi?。(nnn 為當前剩余點的數量)

邊數等于點數減一,這說明點 iii 與其它所有點都有一定的要求,假設要求 bi>bkb_i>b_kbi?>bk?kkkxxx 個,則 ai>ak′a_i>a_k'ai?>ak?k′k'k 也等于 xxx

這種確定的點直接按死不參與后面的討論了。

那么到這里就剩下了一堆邊數 <n?1<n-1<n?1 的點了。

反轉邊的定義,Gˉ=E?G\bar{G}=E-GGˉ=E?G,如果 (u,v)(u,v)(u,v)Gˉ\bar{G}Gˉ 為一條邊當且僅當 (u,v)(u,v)(u,v) 原來是沒有限制的。

這些點都是沒有滿邊的,所以一定會跟至少一個其它點連邊的。

Gˉ\bar{G}Gˉ 形成的是一個生成樹森林,沒有必要多連邊形成圖,獨立是傳遞的,所以 Gˉ\bar{G}Gˉ 是多樣的。

現在連邊的兩個點之間的選擇是互不干涉的。

考慮一個特殊的情況——兩層的菊花圖。有一個非常簡單的構造。

假設菊花圖的根為 uuu,所有葉子依次為 v1,v2,...,vxv_1,v_2,...,v_xv1?,v2?,...,vx?

對于 aaa 序列,au=l,av1=l+1,...,avx?1=l+x?1,avx=l+xa_u=l,a_{v_1}=l+1,...,a_{v_{x-1}}=l+x-1,a_{v_x}=l+xau?=l,av1??=l+1,...,avx?1??=l+x?1,avx??=l+x

對于 bbb 序列,bu=l+1,bv1=l+2,...,bvx?1=l+x,bxv=lb_u=l+1,b_{v_1}=l+2,...,b_{v_{x-1}}=l+x,b_{x_v}=lbu?=l+1,bv1??=l+2,...,bvx?1??=l+x,bxv??=l

用同樣的數字區(qū)間 [l,l+x][l,l+x][l,l+x] 填寫了 a,ba,ba,b 同樣的點集,且打了個等差 111

這樣子,內部反正是沒有限制,不用管數字間的大小,也沒有產生多余的 ai=bia_i=b_iai?=bi? 情況數。

而與外部部分,因為都是用的連續(xù)段數字,相對關系也是滿足的。

例如有個點 ttt 與內部點有相對大小關系的限制,內部用的是 [l,l+x][l,l+x][l,l+x]ttt 所在點無論是 [l′,l)/(l+x,r′][l',l)/(l+x,r'][l,l)/(l+x,r]a,ba,ba,b 都是一致的。要么都小于最小值,要么都大于最大值。

Gˉ\bar{G}Gˉ 中一些邊斷掉是不會出錯的(因為這反而相當于外加了一些限制)。

所以,我們可以就將 Gˉ\bar{G}Gˉ 直接斷成若干個兩層菊花圖。

換言之,最后的答案最少個數可以通過調整構造變成最開始確定的點的數量

有很多種裂成不同菊花圖的方法,下面是官方做法:

枚舉未分配的節(jié)點 uuu

  • 如果 uuu 有臨邊點 vvv 未分配,將 uuu 和所有未分配的 vvv 一起構成一個新的菊花圖,并以 uuu 為根。

  • 否則,說明 uuu 的所有鄰居均已有過分配的菊花圖。隨便選一個鄰居 vvv

    • 如果 vvv 所在的菊花圖至少有 333 個點,那么就可以把 vvv 割裂出來,使得 u,vu,vu,v 成為新的菊花圖。

      注意:vvv 此時不可能是其所在菊花圖的根,如果是那么 uuu 早就隸屬與 vvv 為根的那個菊花圖了。

    • 否則,說明 vvv 所在的菊花圖只有兩個點,將 uuu 加入那個菊花圖,并將那個菊花圖轉變?yōu)橐?vvv 為根即可。

Gˉ\bar{G}Gˉ 中可存在的邊很多,n2n^2n2 級別的,但不一定是全都必須出現的。怎么快速求出想要的生成樹?

用兩個 set 維護已出現在 Gˉ\bar{G}Gˉ 中的點和還未出現的點,在 dfs-tree 的時候順便加邊構出生成樹的邊。

時間復雜度:O((n+m)log?n)O((n+m)\log n)O((n+m)logn)

code

#include <bits/stdc++.h> using namespace std; #define maxn 500005 set < pair < int, int > > graph; set < int > id, G[maxn], R[maxn]; int id1[maxn], id2[maxn], deg[maxn];void dfs( int u ) {id.erase( u );int v = 0;while( 1 ) {auto it = id.upper_bound( v );if( it == id.end() ) break;v = *it;if( G[u].find( v ) != G[u].end() ) continue;R[u].insert( v );R[v].insert( u );dfs( v );} }int main() {int T, n, m;scanf( "%d", &T );while( T -- ) {scanf( "%d %d", &n, &m );for( int i = 1;i <= n;i ++ ) G[i].clear(), R[i].clear();id.clear(); for( int i = 1;i <= n;i ++ ) id.insert( i );for( int i = 1, u, v;i <= m;i ++ ) {scanf( "%d %d", &u, &v );G[u].insert( v );G[v].insert( u );}while( id.size() ) dfs( * id.begin() );int num = n;for( int i = 1;i <= n;i ++ ) {deg[i] = R[i].size();if( deg[i] ) graph.insert( make_pair( deg[i], i ) );else id1[i] = id2[i] = num --;}int l = 0, r = 0, u;while( graph.size() ) {u = graph.begin() -> second;u = *R[u].begin();graph.erase( make_pair( deg[u], u ) );vector < int > scc;for( int v : R[u] ) {graph.erase( make_pair( deg[v], v ) );if( deg[v] == 1 ) scc.push_back( v );else graph.insert( make_pair( -- deg[v], v ) ), R[v].erase( u );}id1[u] = ++ l; for( int i : scc ) id1[i] = ++ l, id2[i] = ++ r; id2[u] = ++ r;}for( int i = 1;i <= n;i ++ ) printf( "%d ", id1[i] ); puts("");for( int i = 1;i <= n;i ++ ) printf( "%d ", id2[i] ); puts("");}return 0; } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的CodeForces1477D Nezzar and Hidden Permutations(构造+调整+菊花图)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。