BalticOI 2020 村莊 貪心

2022-06-27 01:39:12 字數 1184 閱讀 5441

考慮鏈上的情況,最優解肯定是兩兩相鄰的交換,如果還有多,就再多交換一次

因此樹上的也是類似,實際上就是求解乙個最小邊覆蓋問題,選擇一條邊就是交換邊兩端的點編號

可以\(o(n)\)貪心/dp求解樹上最小邊覆蓋

\[\

\]考慮理想的最優情況:對於任意一條邊,我們要求它被經過次數盡可能多

如果這條邊兩端子樹大小分別為\(a,b\),則它被經過的最多次數顯然是\(2\min\\)

考慮找到樹的重心,以它為根,此時任意一顆真子樹的大小\(\leq \frac\)

為了構造最優答案,只需要每棵子樹的集合相互錯開即可

一種簡單的構造方法是:取\(\text\)序,平移\(\frac\)即可得到解

#includeusing namespace std;

typedef long long ll;

#define pb push_back

#define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)

#define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)

template inline void cmax(t &a,t b)

if(!vis[u] && !f) vis[u]=1,swap(ans1[u],ans1[g[u][0]]),min+=2;

}int a[n],c;

int mi=1e9,rt,sz[n];

// 找重心

void dfs(int u,int f)

cmax(ma,n-sz[u]);

if(mi>ma) mi=ma,rt=u;

}// 遍歷dfs序

void dfs_get(int u,int f)

int main()

pre_dfs(1,0),dfs(1,0),dfs_get(rt,0);

rep(i,1,n) ans2[a[i]]=a[(i+n/2-1)%n+1];

printf("%lld %lld\n",min,max);

rep(i,1,n) printf("%d ",ans1[i]);

puts("");

rep(i,1,n) printf("%d ",ans2[i]);

puts("");

}

2 02 理解查詢模型

示例 select name from users where age 10 可以形象的看作是下面這樣 let arr let users users.foreach item 是指列與列之間進行運算得出的結果,叫做廣義投影 因為null 表達的意思是 空 null null false null ...

CI20 2 洗牌演算法

實現乙個方法,對一副牌 52張 進行洗牌,要求洗出的52 組合是的等概率的,即每種組合的概率為1 52 假設已經有乙個完美的隨機數生成器。思路 思路比較直觀,第一次從52張牌中隨機取一張出來,概率為1 52 第二次從剩下的51張隨機取一張出來,概率為1 51 以此類推最終的概率就是1 52 接下來是...

axp202電源管理

問題 充電電流被限制,導致充電時間過長。版本分支 android4.3 master 復現問題,檢測電流變化,發現機器在深度休眠後電流會由原來的1.2a變成0.5a。猜測 可能是由於充電電流過小導致充電時間過長。echo 30 sys class axppower axpreg cat sys cl...