zoukankan      html  css  js  c++  java
  • CF1153D Serval and Rooted Tree

    题意

    分析

    可能是思维题?

    首先我们发现取最小值的操作就尽可能填小的数。

    如果考虑通过“代价”来求得最大值:

    那么其实对于一个取最小值的节点,我们如果定义其代价,很容易发现就是“所有子节点的代价之和”,而最大值呢,就是“所有子节点代价的最小值”。

    我们要让这个代价越小越好,而取最小值显然会让我们不得不使所有数尽可能平均,取最大值显然我们可以极端地只取到最大的那一个。

    于是按照这个设计dp即可,那么其实我们的代价的初始状态就是叶子节点,代价都是1。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    template <typename T>
    inline void read(T &x){
    	x=0;char ch=getchar();bool f=false;
    	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    	while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template <typename T>
    inline void write(T x){
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    #define ll long long
    #define PII pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    const int N=3e5+5,M=2e6+5,INF=1e9+7;
    int n,m,v[N],dp[N],d[N],tot;
    vector<int>vec[N];
    void dfs(int x){
    	if(!d[x]) return dp[x]=1,tot++,void();
    	if(v[x]){
    		dp[x]=INF;
    		for(int y:vec[x]){
    			dfs(y);
    			dp[x]=min(dp[y],dp[x]);
    		}
    	}
    	else{
    		for(int y:vec[x]){
    			dfs(y);
    			dp[x]+=dp[y];
    		}
    	}
    	return ;
    }
    int main(){
    	read(n);
    	for(int i=1;i<=n;i++) read(v[i]);
    	for(int i=2,x;i<=n;i++) read(x),vec[x].pb(i),d[x]++;
    	dfs(1);
    	write(tot-dp[1]+1);
    	return 0;
    }
    
  • 相关阅读:
    短URL
    Linux安装MySQL
    Ubuntu中安装MySQL
    安装交叉工具链arm-linux-gcc
    Linux安装—IP设置
    Linux内核概述
    Bash变量
    Shell登陆
    Linux—查看远程Linux系统运行时间
    Linux—查看路由
  • 原文地址:https://www.cnblogs.com/Akmaey/p/15032275.html
Copyright © 2011-2022 走看看