解题:POI 2013 Triumphal arch

题面

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=300005;
 6 int n,t1,t2,cnt,l,r,mid,ans;
 7 int p[N],noww[2*N],goal[2*N];
 8 int son[N],dp[N];
 9 void link(int f,int t)
10 {
11     noww[++cnt]=p[f];
12     goal[cnt]=t,p[f]=cnt;
13 }
14 void MARK(int nde,int fth)
15 {
16     for(int i=p[nde];i;i=noww[i])
17         if(goal[i]!=fth) MARK(goal[i],nde),son[nde]++;
18 }
19 void DFS(int nde,int fth)
20 {
21     int tmp=0;
22     for(int i=p[nde];i;i=noww[i])
23         if(goal[i]!=fth) DFS(goal[i],nde),tmp+=dp[goal[i]];
24     dp[nde]=max(tmp+son[nde]-mid,0);
25 }
26 bool check(int x)
27 {
28     memset(dp,0xcf,sizeof dp);
29     DFS(1,0); return !dp[1];
30 }
31 int main ()
32 {
33     scanf("%d",&n),r=n;
34     for(int i=1;i<n;i++)
35     {
36         scanf("%d%d",&t1,&t2);
37         link(t1,t2),link(t2,t1);
38     }
39     MARK(1,0);
40     while(l<=r)
41     {
42         mid=(l+r)/2;
43         if(check(mid)) r=mid-1,ans=mid;
44         else l=mid+1;
45     }
46     printf("%d",ans);
47     return 0;
48 }

原文地址:https://www.cnblogs.com/ydnhaha/p/9682674.html

时间: 2024-10-16 10:10:41

解题:POI 2013 Triumphal arch的相关文章

[POI 2013]Bytecomputer(DP)

题目链接 http://main.edu.pl/en/archive/oi/20/baj 题目大意 给你一个长度为n的序列a,序列里每个元素要么是0,要么是-1,要么是1,每次操作可以让a[x]=a[x]+a[x?1],问至少要做多少次操作,才能让整个序列变成非降序列 思路 可以发现,最终的序列是一定是-1 -1 -1--1 -1 -1 0 0 0-0 0 0 1 1 1-1 1 1的形式,肯定没有2或者更大的数字,因为出现这样大的数字是毫无必要的,会增加操作次数.那么可以通过DP解决此题,用f

[bzoj3420]Poi2013 Triumphal arch_树形dp_二分

Triumphal arch 题目链接:https://lydsy.com/JudgeOnline/problem.php?id=3420 数据范围:略. 题解: 首先,发现$ k $具有单调性,我们可以二分. 现在考虑怎么验证? 看了题解... 我们设$ f_i $表示,如果当前人在$i$且要求合法的情况下,$i$的子树中最多要预先处理好多少个节点. 然后暴力树形$dp$转移即可. 代码: #include <bits/stdc++.h> #define N 1000010 using na

Poi 2014 解题报告( 1 - 4 ,6 )

撸了一下Poi 2014 ,看了一下网上题解不多,所以决定写一下.有的题应该是数据不强水过去了,等北京回来在写一下复杂度比较靠谱的代码 o(╯□╰)o 第一题: 题意是给定一个长度不大于1000000,只包括p和j的串,求一个最长的子串,要求子串任何一个前缀和后缀都满足p的数量不少于j的数量. 首先把p当做1,把j当做0,算出前缀和 sum[] ,原来的问题就转化为求一个最长区间 [l,r] ,使得任意的i∈[l,r],都有 sum[i] - sum[l-1] >= 0 并且 sum[r] -

NOIp 2013 Day2 解题报告

NOIp 2013 Day2 解题报告 1.   积木大赛 每次只要选取连续最大的一段区间即可. 继续归纳可得,答案为∑i=1nmax{0,hi-hi-1} 复杂度O(N) 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 8 //variable/

NOIp 2013 Day1 解题报告

NOIp 2013 Day1 解题报告 1.   转圈游戏 不难看出答案就是(x+m*10k) mod n 用快速幂算法,复杂度O(log2k) 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 8 //variable// 9 int n,m,x,

2013年成都邀请赛解题报告

上海邀请赛前拿2013年的成都邀请赛热身,比赛结果大大出乎了我们的预期啊...没做出来的几道题可能还会更新的. A题: 题目地址:HDU 4716 水题..这题是我敲的..敲麻烦了...sad...你们就当没看见吧... 代码: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace

HDU 2013(递推&amp;递归_D题)解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2013 ----------------------------------------------------------------------------------- 题意:每天吃掉一半再多一个,给出第几天吃到只剩一个,求开始时的数量. 思路:递推.按照每天的处理方式反向处理一下,最终得到结果. 代码: #include<cstdio> #include<cstring> #in

解题:POI 2010 Beads

题面 正反各做一遍哈希来判断,然后在两个哈希值里取一个$max/min$做哈希值,然后每次把子串们的哈希插进$set$里,最后统计集合大小,就可以优秀地在$O(nlog^2$ $n)$中出解了 然后我觉得这样太没有理想了,就写了一个挂链哈希表,结果跑的贼慢... 我挂链时的区分方法是换模数再模出一个新值,然后这样做的时候注意要和哈希表的基数和模数区分开 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm>

解题:CQOI 2013 和谐矩阵

题面 踩踩时间复杂度不正确的高斯消元 首先可以发现第一行确定后就可以确定整个矩阵,所以可以枚举第一行的所有状态然后$O(n)$递推检查是否合法 $O(n)$递推的方法是这样的:设$pre$为上一行,$now$为当前行,$nxt$为递推出的下一行,$all$为列的全集,则可以直接用位运算完成递推: $nxt=all\&((now<<1)xor(now>>1)xor$ $now$ $xor$ $pre)$ 递推后第$n+1$行为空则说明可行 问题来了,第一行的状态有$O(2^{