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 ...
随机推荐
- 【Python】【demo实验9】【练习实例】【三数排序】
原题: 输入三个整数x,y,z,请把这三个数由小到大输出. 我的解法: #!/usr/bin/python # encoding=utf-8 # -*- coding: UTF-8 -*- # 输入三 ...
- CrawlerRunner没有Log输出
官网log说明:https://docs.scrapy.org/en/latest/topics/logging.html#scrapy.utils.log.configure_logging 这里记 ...
- ubuntu 设置静态ip,但显示scope global secondary ens33
设置静态ip 修改 /etc/network/interfaces 文件 # The loopback network interface auto lo iface lo inet loopback ...
- 啃掉Hadoop系列笔记(04)-Hadoop运行模式之伪分布式模式
伪分布式模式等同于完全分布式,只是她只有一个节点. 一) HDFS上运行MapReduce 程序 (1)配置集群 (a)配置:hadoop-env.sh Linux系统中获取jdk的安装路径:
- SQLite基础-7.子句(一)
目录 SQLite子句(一) 1. WHERE子句 2. LIKE子句 3. GLOB 子句 4. Oreder By 子句 SQLite子句(一) 1. WHERE子句 WHERE 子句后面跟着条件 ...
- php修改替换数据库图片(文件)
<?php extract($_POST); $date = date('Y-m-d'); $file_name = $_FILES['image']['name'];//获取缓存区图片,格式不 ...
- Linux的一个后门引发对PAM的探究
转自http://www.91ri.org/16803.html 1.1 起因 今天在搜索关于Linux下的后门姿势时,发现一条命令如下:软链接后门: 1 ln -sf /usr/sbin/ssh ...
- 树莓派驱动开发 helloworld
编写Makefile ifneq ($(KERNELRELEASE),) obj-m := MiniX.o else KDIR := /home/hi/pi/kernel/linux/ all: ma ...
- ueditor 编译出错
错误 CS0433 类型“Uploader”同时存在于“com.80community.xy, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nul ...
- MySQL解惑——GROUP BY隐式排序
原文:MySQL解惑--GROUP BY隐式排序 MySQL中GROUP BY隐式排序是什么概念呢? 主要是其它RDBMS没有这样的概念,如果没有认真了解过概念,对这个概念会感觉有点困惑,我们先来看看 ...