zoukankan      html  css  js  c++  java
  • CodeForces 1363E. Tree Shuffling

    题意:

    分析:看到这道题目,我们直观的感受(贪心思考),对于一个节点i,如果i的祖先节点的花费比它小,显然可以让i作为这个祖先节点的子树中的某个节点,因为我们有一个高度更高并且花费更小的节点在它之上,并且管辖它。然后,我们还要考虑不行的局面,对于0-0、1-1的类型,我们没有必要去改动它,我们只需要改动0-1、1-0这种类型的节点,如果总的0-1、1-0不配对(奇偶性不一样),那么就是不可行的局面。我们自底向上的处理每个子树中0-1,1-0的对,看是否能配对,否则作为返回值返回给上面处理

    这道题的想法思路不难,但是对设计搜索的能力要求非常高,等会我会继续编辑讲解怎么设计dfs。

    根据我的经验,首先设计dfs的时候,要把循环分支的子问题当作已经处理好的,然后返回值是处理好多余的配对,如果上面存在一个花费更小,更高的节点,我们这个子树中的配对数量就不要配对了,往上传递再配对,还有就是本层节点的配对数也要加上,这样,基本上都能处理好dfs。


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    const int N = 200005;
    typedef pair<int, int> PII;
    
    int cost[N], b[N], c[N];
    
    int h[N], e[2 * N], ne[2 * N], idx;
    long long res;
    void add(int a, int b)
    {
    	e[idx] = b, ne[idx] = h[a], h[a] = idx++;
    }
    
    PII dfs(int u, int parent, int mn)
    {
    	//本层的遗留配对数,作为返回
    	PII a = { 0, 0 };
    
    	//初值和终值不一样
    	if (b[u] != c[u])
    	{
    		if (b[u])
    			++a.first;
    		else
    			++a.second;
    	}
    
    	for (int i = h[u]; i != -1; i = ne[i])
    	{
    		int j = e[i];
    		if (j == parent) continue;
    		PII p = dfs(j, u, min(mn, cost[u]));
    		//加上从下面返回过来的遗留配对数
    		a.first += p.first;
    		a.second += p.second;
    	}
    	//计算,返回遗留配对数,并且判断是否能被u管辖
    	if (cost[u] < mn)
    	{
    		int take = min(a.first, a.second);
    		res += 2LL * take * cost[u];
    		a.first -= take;
    		a.second -= take;
    	}
    	return a;
    }
    
    int main()
    {
    	//n个节点
    	int n;
    	scanf("%d", &n);
    
    	for (int i = 1; i <= n; ++i)
    	{
    		scanf("%d%d%d", &cost[i], &b[i], &c[i]);
    	}
    
    	memset(h, -1, sizeof h);
    	int u, v;
    	for (int i = 1; i < n; ++i)
    	{
    		scanf("%d%d", &u, &v);
    		add(u, v), add(v, u);
    	}
    
    	pair<int, int> ans = dfs(1, 0, 2e9);
    
    	if (ans.first > 0 || ans.second > 0)
    	{
    		puts("-1");
    	}
    	else
    	{
    		printf("%lld
    ", res);
    	}
    
    	return 0;
    }
    
    
  • 相关阅读:
    Opencv 中透视变换函数对IplImage图像变换时出现的问题?
    algorithm ch15 FastWay
    LeetCode 151 reverse word in a string
    LeetCode 10 Regular Expression Match
    LeetCode the longest palindrome substring
    MS笔试中的一个关于函数返回的“小”题
    js数组
    js数据强转
    css居中问题
    html table
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/13023580.html
Copyright © 2011-2022 走看看