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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

[LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心)

發布時間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

[LOJ 6042]「雅禮集訓 2017 Day7」跳蚤王國的宰相

description

solution

一個到所有節點距離和最小的節點 ?\Leftrightarrow? 樹的重心(滿足最重的兒子最輕,每個兒子siz≤n2\le\frac{n}{2}2n?

顯然原樹的重心答案為0

對于點iii,若要成為新的重心

貪心地有,從原重心的最大兒子邊開始斷,然后直接接在iii

此時把iii提起來當根,則有原來的子樹仍不變,斷掉的若干個子樹接在下面,剩下的所有點為一個子樹

如果原重心斷的子樹節點達到/超過n2\frac{n}{2}2n?,則一定是可以使任意一個iii成為新重心的(剩下節點數不到一半,符合重心設定)

最后的答案一定是cnt/cnt?1,cntcnt/cnt-1,cntcnt/cnt?1,cnt表示重心斷的子樹個數

1的出入是因為有些點可能自己的sizsizsiz足夠大,不需要斷這么多

如圖:紅邊,黃邊為被斷子樹(黃邊為最后一個被斷子樹)

  • iii屬于被斷子樹內(第一個紅點)

    先不斷這個子樹,斷另外的cnt-1個子樹,此時需要判斷總點數n?n-n?其子樹siz[i]?siz[i]-siz[i]?斷掉的子樹used=used=used=剩下的子樹是否>n2>\frac{n}{2}>2n?,超過再斷iii所在rootrootroot的子樹

  • iii屬于殘留子樹(第二個紅點)

    先不斷第cnt被斷子樹(這樣剩下連在一起的子樹節點才最小,才更有可能少斷一條邊),同樣的判斷

code

#include <cstdio> #include <vector> #include <iostream> #include <algorithm> using namespace std; #define maxn 1000005 vector < int > G[maxn]; int n, rt, minn, cnt; int siz[maxn], ans[maxn];void dfs( int u, int fa ) {siz[u] = 1;int max_size = 0;for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i];if( v == fa ) continue;else dfs( v, u );siz[u] += siz[v];max_size = max( max_size, siz[v] );}max_size = max( max_size, n - siz[u] );if( max_size < minn ) {minn = max_size;rt = u;} } int GetRoot() {minn = 0x7f7f7f7f;dfs( 1, 0 );return rt; }bool cmp( const int x, const int y ) {return siz[x] > siz[y]; }void solve( int u, int fa, int used ) {ans[u] = cnt + ( ( ( n - siz[u] - used ) << 1 ) > n );for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i];if( v == fa ) continue;else solve( v, u, used );} }int main() {scanf( "%d", &n );for( int i = 1, u, v;i < n;i ++ ) {scanf( "%d %d", &u, &v );G[u].push_back( v );G[v].push_back( u );}int root = GetRoot();dfs( root, 0 );sort( G[root].begin(), G[root].end(), cmp );int tot = 0;for( int i = 0;i < G[root].size();i ++ ) {tot += siz[G[root][i]];if( ( tot << 1 ) >= n ) break;cnt ++;}for( int i = 0;i < G[root].size();i ++ )solve( G[root][i], root, tot - max( siz[G[root][i]], siz[G[root][cnt]] ) );for( int i = 1;i <= n;i ++ )printf( "%d\n", ans[i] );return 0; }

總結

以上是生活随笔為你收集整理的[LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心)的全部內容,希望文章能夠幫你解決所遇到的問題。

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