zoukankan      html  css  js  c++  java
  • JZOJ 【2020.11.30提高组模拟】剪辣椒(chilli)

    题目大意

    给出一棵 (n) 个节点的树,删去其中两条边
    使得分出的三个子树大小中最大与最小的差最小

    分析

    先一边 (dfs) 预处理出以 (1) 为根每个点的 (size)
    然后按 (dfs) 的顺序枚举一个点,表示删去这个点返回父亲的边
    记这个点为 (x)
    分类讨论
    第一种情况是删去当前点到根的一条边,记这条边下面的点为 (y)
    这种情况会使子树 (y) 包含子树 (x)
    第二种情况是删去不包含子树 (x) 的已经遍历过的边
    这种情况须令外处理
    于是我们算答案是要做两遍 (dfs)
    具体细节看代码

    (Code)

    #include<cstdio>
    #include<iostream>
    #include<set>
    using namespace std;
    
    const int N = 2e5 + 5;
    int n, h[N], siz[N], ans;
    set<int> s;
    set<int>::iterator it;
    struct edge{int to, nxt;}e[N << 1];
    
    void add(int x, int y)
    {
    	static int tot = 0;
    	e[++tot] = edge{y, h[x]}, h[x] = tot;
    }
    
    void dfs(int x, int fa)
    {
    	siz[x] = 1;
    	for(register int i = h[x], v; i; i = e[i].nxt)
    	{
    		v = e[i].to;
    		if (v == fa) continue;
    		dfs(v, x), siz[x] += siz[v];
    	}
    }
    
    int getc(int x, int y, int z)
    {
    	int a = max(max(x, y), z), b = min(min(x, y), z);
    	return a - b;
    }
    
    void calc(int x)
    {
    	int d = (n - siz[x]) >> 1;
    	it = s.lower_bound(d);
    	if (it != s.end()) ans = min(ans, getc(siz[x], *it, n - siz[x] - *it));
    	if (it != s.begin()) --it, ans = min(ans, getc(siz[x], *it, n - siz[x] - *it));
    }
    
    void dfs1(int x, int fa)
    {
    	calc(x);
    	s.insert(n - siz[x]);
    	for(register int i = h[x], v; i; i = e[i].nxt)
    	{
    		v = e[i].to;
    		if (v == fa) continue;
    		dfs1(v, x);
    	}
    	s.erase(n - siz[x]);
    }
    
    void dfs2(int x, int fa)
    {
    	for(register int i = h[x], v; i; i = e[i].nxt)
    	{
    		v = e[i].to;
    		if (v == fa) continue;
    		calc(v), dfs2(v, x);
    	}
    	s.insert(siz[x]);
    }
    
    int main()
    {
    	freopen("chilli.in", "r", stdin);
    	freopen("chilli.out", "w", stdout);
    	scanf("%d", &n);
    	for(register int i = 1, x, y; i < n; i++) scanf("%d%d", &x, &y), add(x, y), add(y, x);
    	ans = 0x3f3f3f3f, dfs(1, 0), dfs1(1, 0), s.clear(), dfs2(1, 0);
    	printf("%d", ans);
    }
    
  • 相关阅读:
    CenOS下搭建PPTP服务
    Nginx做反向代理总是被系统kill
    python排序算法
    linux系统中rsync+inotify实现服务器之间文件实时同步
    HDU
    BZOJ1237: [SCOI2008]配对
    BZOJ2243: [SDOI2011]染色
    BZOJ3192: [JLOI2013]删除物品
    点分治小结
    AtCoder Beginner Contest 124 解题报告
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/14062349.html
Copyright © 2011-2022 走看看