Codeforce 1401 D. Maximum Distributed Tree 解析(思維、DFS、組合、貪心、DP)

今天我們來看看CF1401D

題目連結

題目

直接看原題比較清楚,略。

前言

這次比賽被第C.題搞到剩20分鐘可以寫D.這題,比賽時沒寫出來,比完了以後花了一個多小時Debug才De出來Orz。

想法

要注意到,題目中的distribution index實際上就是把每條路對於每個點對互相拜訪時,會被經過幾次,乘個權重,全部加起來。例如說\((u,v)\)這條邊,\(u\)那一端接了一個節點個數為\(cnt_u\)的子樹,\(v\)那一端接了一個節點個數為\(cnt_v\)的子樹(code中我是用\(dp[.]\)來儲存),那麼總共有\(cnt_u\times cnt_v\)個點對,在互相拜訪時會經過\((u,v)\)這條邊,而distribution index就是把所有邊的拜訪次數乘以你分配的權重,然後全部加起來。

而對於每條邊,如果要找到兩個節點分別連接到多大的子樹(注意,這邊所說的子樹代表由當前點為根,且不會經過目前考慮的邊的子樹),我們可以隨便選一個點\(r\)為根,做樹上DP維護每個點為根,往下的子樹(也就是以\(r\)為根來說,我們考慮的子樹不會往\(r\)接近)的節點個數。接著就是一些簡單的實作了。

要注意以下幾點:

  1. 對於某個邊\((u,v)\),這個邊會被經過的次數為:\(dp[v]\times(n-dp[v])\) (假設\(u\)比\(v\)淺,需要先在dfs時維護每個點的depth)
  2. 最後把權重分配到邊上時,首先當然兩個數列都要先排序,接著要記得考慮\(n-1>m\)和\(n-1\le m\)的情況(我就是在這裡卡了一個多小時)

程式碼:

int _n=1e5+10;
int t,n,m,p[_n],x,y,dp[_n],dep[_n];
VI G[_n];
PII e[_n];
ll ecnt[_n];
void dfs(int v,int fa,int d){
dep[v]=d;
if(SZ(G[v])==1 and G[v][0]==fa){dp[v]=1;return;}
int res=1;
rep(i,0,SZ(G[v]))if(fa!=G[v][i])dfs(G[v][i],v,d+1),res+=dp[G[v][i]];
dp[v]=res;
}
main(void) {ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>t;while(t--){
cin>>n;rep(i,0,n)G[i].clear();
rep(i,0,n-1){cin>>x>>y;x--,y--;G[x].pb(y),G[y].pb(x);e[i]={x,y};}
cin>>m;rep(i,0,m)cin>>p[i]; sort(p,p+m);
dfs(0,-1,0); ll ans=0;rep(i,0,n-1){
int u=e[i].fi,v=e[i].se;
if(dep[u]>dep[v])swap(u,v);
ecnt[i]=1ll*dp[v]*(n-dp[v]);
} sort(ecnt,ecnt+n-1);
int len=max(0,n-1-m);
rep(i,0,len)ans+=ecnt[i],ans%=mod;
if(n-1>m)rep(i,len,len+m)ans+=1ll*p[i-len]*ecnt[i],ans%=mod;
if(m>=n-1){
rep(i,0,n-2)ans+=1ll*p[i]*ecnt[i],ans%=mod;
ll tmp=1;rep(i,n-2,m)tmp*=1ll*p[i],tmp%=mod;
ans+=1ll*tmp*(ecnt[n-2]%mod); ans%=mod;
}
cout<<ans<<'\n';
}
return 0;
}

標頭、模板請點Submission看

Submission

D. Maximum Distributed Tree 解析(思維、DFS、組合、貪心、DP)的更多相关文章

  1. D. Rescue Nibel! 解析(思維、組合、離散化、差分)

    Codeforce 1420 D. Rescue Nibel! 解析(思維.組合.離散化.差分) 今天我們來看看CF1420D 題目連結 題目 給你\(n\)個區間,求有幾種方法使得\(k\)個區間的 ...

  2. E. Xenia and Tree 解析(思維、重心剖分)

    Codeforce 342 E. Xenia and Tree 解析(思維.重心剖分) 今天我們來看看CF342E 題目連結 題目 給你一棵樹,有兩種操作,把某點標成紅色或者查詢離某點最近的紅點有多遠 ...

  3. E. Tree Queries 解析(思維、LCA)

    Codeforce 1328 E. Tree Queries 解析(思維.LCA) 今天我們來看看CF1328E 題目連結 題目 給你一棵樹,並且給你\(m\le2e5\)個詢問(包含\(k\)個點) ...

  4. B. Kay and Snowflake 解析(思維、DFS、DP、重心)

    Codeforce 685 B. Kay and Snowflake 解析(思維.DFS.DP.重心) 今天我們來看看CF685B 題目連結 題目 給你一棵樹,要求你求出每棵子樹的重心. 前言 完全不 ...

  5. E. Tree Reconstruction 解析(思維)

    Codeforce 1041 E. Tree Reconstruction 解析(思維) 今天我們來看看CF1041E 題目連結 題目 略,請直接看原題 前言 一開始完全搞錯題目意思,還以為每次會刪除 ...

  6. D. New Year Santa Network 解析(思維、DFS、組合、樹狀DP)

    Codeforce 500 D. New Year Santa Network 解析(思維.DFS.組合.樹狀DP) 今天我們來看看CF500D 題目連結 題目 給你一棵有邊權的樹,求現在隨機取\(3 ...

  7. B. Two Fairs 解析(思維、DFS、組合)

    Codeforce 1276 B. Two Fairs 解析(思維.DFS.組合) 今天我們來看看CF1276B 題目連結 題目 給一個連通圖,並給兩個點(\(a,b\)),求有多少點對使得:任一路徑 ...

  8. C2. Pokémon Army (hard version) 解析(思維)

    Codeforce 1420 C2. Pokémon Army (hard version) 解析(思維) 今天我們來看看CF1420C2 題目連結 題目 略,請直接看原題. 前言 根本想不到這個等價 ...

  9. D. Generating Sets 解析(思維)

    Codeforce 722 D. Generating Sets 解析(思維) 今天我們來看看CF722D 題目連結 題目 略,請直接看原題 前言 真的是沒想到... @copyright petje ...

随机推荐

  1. Shell学习(四)Shell运算符

    一.基础运算 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用. expr 是一款表达式计算工具,使用它能完成表达式的求值操作. #计算两个数 ...

  2. Presto 标量函数注册和调用过程简述

    在Presto 函数开发一文中已经介绍过如何进行函数开发,本文主要讲述标量函数(Scalar Function)实现之后,是如何在Presto内部进行注册和被调用的.主要讲述标量函数是因为:三类函数的 ...

  3. spark 笔记2

    一.Spark Shuffle 的发展 Spark 0.8及以前 Hash Based Shuffle Spark 0.8.1 为Hash Based Shuffle引入File Consolidat ...

  4. 理解vue与MVVM三要素

    MVVM到底是什么,跟Jquery有什么区别? MVVM理解,跟MVC区别 Model View Controller,一般是用户操作view视图按钮,触发controller内方法,cotrolle ...

  5. Python-统计序列中元素

    问题1: 随机数列[12,5,8,7,8,9,4,8,5,...] 中出现次数最高的3个元素,他们出现的次数 问题2: 对某英文文章的单词,进行词频统计,找出出现次数最搞得10个单词,他们出现的次数是 ...

  6. 免费开源工作流Smartflow-Sharp v2.0

    @font-face { font-family: 宋体 } @font-face { font-family: "Cambria Math" } @font-face { fon ...

  7. vs工程生成dll文件及其调用方法

    转载:https://blog.csdn.net/weixin_44536482/article/details/91519413 vs工程生成dll文件及其调用方法                  ...

  8. Linux批量查找与替换

    Linux批量查找并替换文件夹下所有文件的内容 经常要使用到 Linux的批量查找与替换,这里为大家介绍使用 sed 命令和 grep 命令的结合来实现查找文件中的内容并替换. 语法格式: sed - ...

  9. vue 下载jquery 下载layui-layer 下载vue-router

    1.下载jquery cmd:语句 npm install jquery 然后在main.js文件里面写 import $ from 'jquery' 2.下载layui-layer 在vue里面的l ...

  10. SpringBoot logback 配置文件自定义属性

    添加自定义属性类 package com.cus.config; import ch.qos.logback.core.PropertyDefinerBase; import org.springfr ...