【GDOI2018模拟9.23】博弈
来源:互联网 发布:按照文件夹恢复数据 编辑:程序博客网 时间:2024/05/20 12:48
Description:
1<=n<=10^6
题解:
首先策略肯定是把Tom逼到一个点,然后去删边,接着取消标记让Tom一步步走到T那儿去。
Tom肯定会往代价最大的地方钻,1/4可以选择封住最大的先,然后Tom往次大的走。
以b为根,建树。
对于不在b->t的路径上的点,求出w,表示往它的子树中走一圈回来的最小代价,dp显然。
现在你可以想像从b->t走,你可以删掉相邻的子树,但是你不知道删哪棵。
于是二分答案,遵循能删必删的思想,就可以确定了,直到某个深度不行了。
Code:
#include<cstdio>#include<cstring>#include<algorithm>#define fo(i, x, y) for(int i = x; i <= y; i ++)#define fd(i, x, y) for(int i = x; i >= y; i --)#define max(a, b) ((a) > (b) ? (a) : (b))using namespace std;const int N = 1e6 + 5;int n, s, t, x, y, sum;int final[N], next[N * 2], to[N * 2], tot;int w[N], bz[N], sum_son[N], fa[N];int d[N], bz_d[N];void link(int x, int y) { next[++ tot] = final[x], to[tot] = y, final[x] = tot; next[++ tot] = final[y], to[tot] = x, final[y] = tot;}void dg(int x) { if(x == t) return; bz[x] = 1; for(int i = final[x]; i; i = next[i]) { int y = to[i]; if(bz[y]) continue; sum_son[x] ++; fa[y] = x; dg(y); } bz[x] = 0;}void Build(int x) { while(x != s) d[++ d[0]] = x, bz_d[x] = 1, x = fa[x]; d[++ d[0]] = x; fo(i, 2, d[0]) sum += sum_son[d[i]]; sum -= (d[0] - 1);}void dg2(int x) { if(x == t) return; bz[x] = 1; int mx = 0, mx2 = 0; for(int i = final[x]; i; i = next[i]) { int y = to[i]; if(bz[y]) continue; if(!bz_d[y]) w[y] = w[x] + sum_son[y]; dg2(y); if(w[y] > mx) { mx2 = mx; mx = w[y]; } else if(w[y] > mx2) { mx2 = w[y]; } } w[x] = mx2 + sum_son[x]; bz[x] = 0;}int pd(int m) { int yige = 0; fd(i, d[0], 2) { int dep = d[0] - i + 1; int ss = 0; int x = d[i]; for(int j = final[x]; j; j = next[j]) { int y = to[j]; if(bz_d[y] || fa[y] != x) continue; if(w[y] + sum > m - yige) ss ++; } if(ss > dep - yige) return 0; yige += ss; if(m < yige) return 0; sum -= sum_son[x] - 1; } return 1;}int main() { freopen("compete.in", "r", stdin); freopen("compete.out", "w", stdout); scanf("%d %d %d", &n, &t, &s); fo(i, 1, n - 1) { scanf("%d %d", &x, &y); link(x, y); } dg(s); Build(t); dg2(s); int ans = 0; for(int l = 0, r = n; l <= r; ) { int m = (l + r) / 2; int sum2 = sum; if(pd(m)) ans = m, r = m - 1; else l = m + 1; sum = sum2; } printf("%d", ans);}
阅读全文
0 0
- 【GDOI2018模拟9.23】博弈
- 【GDOI2018模拟9.23】动态图
- 【GDOI2018模拟9.23】动态图
- JZOJ 5387【GDOI2018模拟9.23】动态图
- 【GDOI2018模拟7.6】吃干饭
- 【GDOI2018模拟7.9】期末考试
- 【GDOI2018模拟7.8】质数
- 【GDOI2018模拟7.8】矩阵
- 【GDOI2018模拟7.10】B
- 【GDOI2018模拟7.10】C
- 【GDOI2018模拟7.10】B
- 【GDOI2018模拟7.10】C
- 【GDOI2018模拟7.12】B
- 【GDOI2018模拟7.12】C
- 【GDOI2018模拟7.12】A
- 【GDOI2018模拟7.10】C
- 【GDOI2018模拟8.11】质数
- 【GDOI2018模拟8.11】质数
- .NET编程(03)Lambda&Linq(to object)
- 如何转载大神的博客
- 信号
- a标签跳转到配置有angular路由的页面,并控制显示view中的内容
- 深入理解js中的加载事件
- 【GDOI2018模拟9.23】博弈
- 深入了解 WPF Dispatcher 的工作原理(Invoke/InvokeAsync 部分)
- google guava使用例子
- SQL执行顺序
- MFC中用CFile读取和写入文件
- 在Linux上(我的服务器是Ubuntu) 用redis-trib.rb搭建redis集群,并在客户端使用spring-data-redis连接(亲测)
- 2017年“华信智原杯”安徽省大学生程序设计大赛C题刷票
- 用phpstrom编辑器编辑linux服务器上的远程项目
- Quartus引脚分配【转载】