zoukankan      html  css  js  c++  java
  • HDU6035 2017多校第一场1003 树形DP

    参考:Bahuia的博客

    重点在于理清子树的层次关系,对于单个点进行逐子树更新时的转移

    #pragma comment(linker, "/STACK:1024000000,1024000000") 
    #include<bits/stdc++.h>
    #include<stdio.h>
    #include<algorithm>
    #include<queue>
    #include<string.h>
    #include<iostream>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<iomanip>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define FOR(a) for(int i=1;i<=a;i++)
    
    const int maxn=2e5+7;
    
    int vis[maxn];
    int color[maxn];
    int siz[maxn];
    ll sum[maxn];	//遍历到当前位置,颜色为x的最高一批节点为根的子树大小
    
    vector<int>G[maxn];
    ll ans;
    
    ll dfs(int u,int fa){
    	siz[u]=1;
    	ll allson=0;
    	int sz=G[u].size();
    	for(int i=0;i<sz;i++){
    		int v=G[u][i];if(v==fa)continue;
    		ll pre=sum[color[u]];	//递归前的sum值
    		siz[u]+=dfs(v,u);
    		ll add=sum[color[u]]-pre;//新链上的块大小
    		ans+=(siz[v]-add)*(siz[v]-add-1)/2;
    		allson+=siz[v]-add;		//记录儿子节点v组成的连通块大小
    	}
    	sum[color[u]]+=allson+1;
    	return siz[u];
    }
    
    int main(){
    	int n,kase=0;
    	while(~scanf("%d",&n)){
    		memset(vis,0,sizeof vis);
    		memset(sum,0,sizeof sum);
    		int cnt=0;
    		for(int i=1;i<=n;i++){
    			scanf("%d",&color[i]);
    			if(!vis[color[i]])cnt++;
    			vis[color[i]]=1;
    			G[i].clear();
    		}
    		for(int i=1;i<n;i++){
    			int u,v;
    			scanf("%d%d",&u,&v);
    			G[u].pb(v);G[v].pb(u);
    		}
    		printf("Case #%d: ",++kase);
    		if(cnt==1){
    			printf("%lld
    ",1ll*n*(n-1)/2);continue;
    		}
    		ans=0;
    		dfs(1,-1);
    		for(int i=1;i<=n;i++){
    			if(!vis[i])continue;
    			ans+=(n-sum[i])*(n-sum[i]-1ll)/2ll;
    		}
    		printf("%lld
    ",1ll*n*(n-1)/2ll*cnt-ans);
    	}
    }
    
    


  • 相关阅读:
    Git学习-创建版本库
    使用Vim编辑器,如何退出
    设置既定目录的命令提示符
    字符数组和字符串
    一波杂乱的分享
    全国软件设计大赛C/C++语言练习
    HDU 1720、1062、2104、1064、2734、1170、1197、2629
    hdu 2000-2010 ACM
    HDU——算法练习1000 1089-1096
    爬虫学习笔记之为什么要设置超时时间,怎么设置(使用selenium)
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611300.html
Copyright © 2011-2022 走看看