P3554 [POI2013]LUK-Triumphal arch
生活随笔
收集整理的這篇文章主要介紹了
P3554 [POI2013]LUK-Triumphal arch
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
\(\color{#0066ff}{ 題目描述 }\)
給一顆樹,1號節點已經被染黑,其余是白的,兩個人輪流操作,一開始B在1號節點,A選擇k個點染黑,然后B走一步,如果B能走到A沒染的節點則B勝,否則當A染完全部的點時,A勝。求能讓A獲勝的最小的k
\(\color{#0066ff}{輸入格式}\)
第一行:n
然后是n-1條邊
\(\color{#0066ff}{輸出格式}\)
最小的k
\(\color{#0066ff}{輸入樣例}\)
7 1 2 1 3 2 5 2 6 7 2 4 1\(\color{#0066ff}{輸出樣例}\)
3\(\color{#0066ff}{數據范圍與提示}\)
\(1\leq n \leq 300000\)
\(\color{#0066ff}{ 題解 }\)
考慮當前B在一個點上,首先,他肯定不會走回頭路,因為來的路一定都被染黑了,肯定不優的
如果當前點的子樹個數>k,那么顯然A是不能全染黑的,B就有機可乘了qwq
如果子樹個數不足,那么顯然剩下的一些染色機會就會被分配到子樹中去
我們設f[i]表示將i的子樹全部染黑(不包括i)還需要幾次
則\(f[u] = \sum{(f[v]+1)} - k\)
二分ans,我們只需判\(f[1]\)是否為0即可
#include<bits/stdc++.h> #define LL long long LL in() {char ch; LL x = 0, f = 1;while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));return x * f; } struct node {int to;node *nxt;node(int to = 0, node *nxt = NULL): to(to), nxt(nxt) {}void *operator new (size_t) {static node *S = NULL, *T = NULL;return (S == T) && (T = (S = new node[1024]) + 1024), S++;} }; const int maxn = 3e5 + 100; int f[maxn]; node *head[maxn]; int n; void add(int from, int to) {head[from] = new node(to, head[from]); } void dfs(int x, int fa, int mid) {f[x] = 0;for(node *i = head[x]; i; i = i->nxt) {if(i->to == fa) continue;dfs(i->to, x, mid);f[x] += (f[i->to] + 1);}f[x] = std::max(0, f[x] - mid); } bool ok(int mid) {dfs(1, 0, mid);return f[1] == 0; } int main() {n = in();int x, y;for(int i = 1; i < n; i++) {x = in(), y = in();add(x, y), add(y, x);}int l = 0, r = n, ans = n;while(l <= r) {int mid = (l + r) >> 1;if(ok(mid)) ans = mid, r = mid - 1;else l = mid + 1;}printf("%d\n", ans);return 0; }轉載于:https://www.cnblogs.com/olinr/p/10237917.html
總結
以上是生活随笔為你收集整理的P3554 [POI2013]LUK-Triumphal arch的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 内联 外联_sql中的内联和
- 下一篇: 书摘---创业36条军规2:创业的三大条