HDU 6035 - Colorful Tree | 2017 Multi-University Training Contest 1
- /*
- HDU 6035 - Colorful Tree [ DFS,分块 ]
- 题意:
- n个节点的树,每个节点有一种颜色(1~n),一条路径的权值是这条路上不同的颜色的数量,问所有路径(n*(n-1)/2条) 权值之和是多少?
- 分析:
- 考虑单种颜色,这种颜色的贡献是 至少经过一次这种颜色的路径数 = 总路径数(n*(n-1)/2) - 没有经过这种颜色的路径数
- 求没有经过这种颜色的路径数,即这种颜色的点将整棵树分块,每个分块中的总路径数
- */
- #include <bits/stdc++.h>
- using namespace std;
- #define LL long long
- const int N = 200005;
- struct Edge {
- int to, next;
- }edge[N<<1];
- int tot, head[N];
- void init() {
- memset(head, -1, sizeof(head));
- tot = 0;
- }
- void addedge(int u, int v) {
- edge[tot].to = v; edge[tot].next = head[u];
- head[u] = tot++;
- }
- int n;
- int c[N], last[N], rem[N], cut[N];
- LL ans;
- LL sum2(LL x) {
- return x*(x-1)/2;
- }
- int dfs(int u, int pre)
- {
- int su = 1, fa = last[c[u]];
- last[c[u]] = u;
- for (int i = head[u]; i != -1; i = edge[i].next)
- {
- int v = edge[i].to;
- if (v == pre) continue;
- cut[u] = 0;
- int sv = dfs(v, u);
- su += sv;
- ans -= sum2(sv-cut[u]);
- }
- (fa ? cut[fa] : rem[c[u]]) += su;
- last[c[u]] = fa;
- return su;
- }
- int main()
- {
- int tt = 0;
- while (~scanf("%d", &n))
- {
- init();
- for (int i = 1; i <= n; i++) scanf("%d", &c[i]);
- for (int i = 1; i < n; i++)
- {
- int x, y; scanf("%d%d", &x, &y);
- addedge(x, y); addedge(y, x);
- }
- memset(last, 0, sizeof(last));
- memset(cut, 0, sizeof(cut));
- memset(rem, 0, sizeof(rem));
- ans = n*sum2(n);
- dfs(1, 1);
- for (int i = 1; i <= n; i++)
- ans -= sum2(n-rem[i]);
- printf("Case #%d: %lld\n", ++tt, ans);
- }
- }
- //----------------------------------------------------------------------
- #include <bits/stdc++.h>
- using namespace std;
- #define LL long long
- const int N = 200005;
- vector<int> c[N], G[N];
- int n;
- int L[N], R[N], s[N], f[N];
- void dfs(int u, int pre, int&& ncnt)
- {
- f[u] = pre;
- L[u] = ++ncnt;
- s[u] = 1;
- for (auto& v : G[u])
- {
- if (v == pre) continue;
- dfs(v, u, move(ncnt));
- s[u] += s[v];
- }
- R[u] = ncnt;
- }
- bool cmp(int a, int b) {
- return L[a] < L[b];
- }
- int main()
- {
- int tt = 0;
- while (~scanf("%d", &n))
- {
- for (int i = 0; i <= n; i++) c[i].clear(), G[i].clear();
- for (int i = 1; i <= n; i++)
- {
- int x; scanf("%d", &x);
- c[x].push_back(i);
- }
- for (int i = 1; i < n; i++)
- {
- int x, y; scanf("%d%d", &x, &y);
- G[x].push_back(y);
- G[y].push_back(x);
- }
- G[0].push_back(1);
- dfs(0, 0, 0);
- LL ans = (LL)n * n * (n-1)/2;
- for (int i = 1; i <= n; i++)
- {
- if (c[i].empty()) {
- ans -= (LL)n*(n-1)/2;
- continue;
- }
- c[i].push_back(0);
- sort(c[i].begin(), c[i].end(), cmp);
- for (auto& x : c[i])
- for (auto& y : G[x])
- {
- if (y == f[x]) continue;
- int size = s[y];
- int k = L[y];
- while (1)
- {
- L[n+1] = k;
- auto it = lower_bound(c[i].begin(), c[i].end(), n+1, cmp);
- if (it == c[i].end() || L[*it] > R[y]) break;
- size -= s[*it];
- k = R[*it]+1;
- }
- ans -= (LL)size * (size-1)/2;
- }
- }
- printf("Case #%d: %lld\n", ++tt, ans);
- }
- }
HDU 6035 - Colorful Tree | 2017 Multi-University Training Contest 1的更多相关文章
- hdu 6035:Colorful Tree (2017 多校第一场 1003) 【树形dp】
题目链接 单独考虑每一种颜色,答案就是对于每种颜色至少经过一次这种的路径条数之和.反过来思考只需要求有多少条路径没有经过这种颜色即可. 具体实现过程比较复杂,很神奇的一个树形dp,下面给出一个含较详细 ...
- 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】
Colorful Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- HDU 6035 Colorful Tree(补集思想+树形DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6035 [题目大意] 给出一颗树,一条路径的价值为其上点权的种类数,求路径总价值 [题解] 单独考虑 ...
- HDU 6035 Colorful Tree (树形DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6035 [题目大意] 给出一颗树,一条路径的价值为其上点权的种类数,求路径总价值 [题解] 我们计算 ...
- 2017ACM暑期多校联合训练 - Team 1 1003 HDU 6035 Colorful Tree (dfs)
题目链接 Problem Description There is a tree with n nodes, each of which has a type of color represented ...
- HDU 6035 Colorful Tree(dfs)
题意:一棵有n个点的树,树上每个点都有颜色c[i],定义每条路径的值为这条路径上经过的不同颜色数量和.求所有路径的值的和. 可以把问题转化为对每种颜色有多少条不同的路径至少经过这种颜色的点,然后加和. ...
- hdu 6035 Colorful Tree(虚树)
考虑到树上操作:首先题目要我们求每条路径上出现不同颜色的数量,并把所有加起来得到答案:我们知道俩俩点之间会形成一条路径,所以我们可以知道每个样例的总的路径的数目为:n*(n-1)/2: 这样单单的求, ...
- HDU 6170 - Two strings | 2017 ZJUT Multi-University Training 9
/* HDU 6170 - Two strings [ DP ] | 2017 ZJUT Multi-University Training 9 题意: 定义*可以匹配任意长度,.可以匹配任意字符,问 ...
- hdu 6301 Distinct Values (2018 Multi-University Training Contest 1 1004)
Distinct Values Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
随机推荐
- [转帖]docker容器保持运行不退出
docker容器保持运行不退出 2019年01月20日 23:21:22 chvalrous 阅读数 1511 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...
- Javascript - BOM 对象
浏览器相关的对象.获取浏览器相关的信息,可以设置和修改浏览器属性. 0. web-app 版 TodoList 小程序 用以下内容可以自己手写一个 TodoList 小程序,再添加几行代码就可以用手机 ...
- TUM 慕尼黑工业大学 MSEI 课程结构介绍 ws19/20
本文内容 根据德文 tum 官网介绍:https://www.ei.tum.de/studium/master-ei-msei/ 翻译,提取并且翻译成中文信息. 本文适用于ws19/20届的学生. 概 ...
- php面试相关整理
1.HTTP Keep-Alive的作用 作用:Keep-Alive:使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接.Web服务器,基 ...
- PHPstorm配置同步服务器文件
一.配置服务器 1.连接配置 打开菜单栏 Tools -> Deployment -> Configuration 点击 + 选择 SFTP,并填写相关服务器信息: Type:连接类型,这 ...
- linux 下用find命令查找文件,rm命令删除文件
linux 下用find命令查找文件,rm命令删除文件. 删除指定目录下指定文件find 要查找的目录名 -name .svn |xargs rm -rf 删除指定名称的文件或文件夹: find -t ...
- HashMap—— values() remove方法 containsKey()方法 containsValue()方法
values()方法:看下面的实例,就是把所有的value值封装成一个connection型的数组 Map<Integer,Student> students=new HashMap< ...
- C#中word文档转html
var path = Request.Url.Host + ":" + Request.Url.Port + list[i].AnnexPath; //html保存路径 strin ...
- 题解luoguP2054 BZOJ1965【[AHOI2005]洗牌】
题目链接: https://www.luogu.org/problemnew/show/P2054 https://www.lydsy.com/JudgeOnline/problem.php?id=1 ...
- STM32F10xxx_异常与中断
STM32F10xxx_异常与中断 [TOC] 更新记录 version status description date author V1.0 C Create Document 2018.10.2 ...