CSUOJ1811 Tree Intersection (启发式合并)
Input
OutputFor each set, (n-1) integers R 1,R 2,…,R n-1.Sample Input
- 4
- 1 2 2 1
- 1 2
- 2 3
- 3 4
- 5
- 1 1 2 1 2
- 1 3
- 2 3
- 3 5
- 4 5
Sample Output
- 1
- 2
- 1
- 1
- 1
- 2
- 1
Hint
题解:题意就是,给以一颗树n个节点,每个节点有一种颜色,然年后对于n-1条边,如果把一条边截断,让你求两颗子树有多少种相同的颜色,依次输入每一条边的答案。
启发式搜索,分别记录点和边的答案;如果点u和其子树某种颜色的数量已经等于总量了,那么对于该子树外的一部分,就没有该中颜色了,答案-1;如果小于总量,答案+1;
然后更新u节点该颜色的数量即可;
参考代码:
- #include<bits/stdc++.h>
- using namespace std;
- #define clr(a,val) memset(a,val,sizeof (a))
- #define pb push_back
- #define fi first
- #define se second
- typedef long long ll;
- const int maxn=1e5+;
- inline int read()
- {
- int x=,f=;char ch=getchar();
- while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
- while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
- return x*f;
- }
- struct Edge{
- int to,index,nxt;
- } edge[maxn<<];
- int n,head[maxn<<],tot;
- int col[maxn],sum[maxn],ans[maxn],res[maxn<<];//ans[u]表示u点及子节点的答案, res[edge]表示边的答案
- map<int,int> cnt[maxn];//cnt[u][color] 表示u点子树color颜色有多少个节点
- inline void Init()
- {
- clr(head,-);clr(sum,); tot=;
- for(int i=;i<=n;++i) cnt[i].clear();
- }
- inline void addedge(int u,int v,int id)
- {
- edge[tot].to=v;
- edge[tot].index=id;
- edge[tot].nxt=head[u];
- head[u]=tot++;
- }
- inline void dfs(int u,int fa,int id)
- {
- cnt[u][col[u]]=;
- ans[u] = cnt[u][col[u]]<sum[col[u]]?:;
- for(int e=head[u];~e;e=edge[e].nxt)
- {
- int v=edge[e].to;
- if(v==fa) continue;
- dfs(v,u,edge[e].index);
- if(cnt[u].size()<cnt[v].size())
- {
- swap(cnt[u],cnt[v]);
- swap(ans[u],ans[v]);
- }
- map<int,int>::iterator it;
- for(it=cnt[v].begin();it!=cnt[v].end();it++)
- {
- if(!cnt[u][(*it).fi] && (*it).se<sum[(*it).fi]) ++ans[u];
- else if(cnt[u][(*it).fi] && cnt[u][(*it).fi]+(*it).se==sum[(*it).fi]) --ans[u];
- cnt[u][(*it).fi]+=(*it).se;//加上子树的数量
- }
- }
- res[id]=ans[u];
- }
- int main()
- {
- while(~scanf("%d",&n))
- {
- Init();
- for(int i=;i<=n;++i) col[i]=read(),sum[col[i]]++;
- for(int i=;i<n;++i)
- {
- int u=read(),v=read();
- addedge(u,v,i);addedge(v,u,i);
- }
- dfs(,,);
- for(int i=;i<n;++i) printf("%d\n",res[i]);
- }
- return ;
- }
CSUOJ1811 Tree Intersection (启发式合并)的更多相关文章
- csu oj 1811: Tree Intersection (启发式合并)
题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1811 给你一棵树,每个节点有一个颜色.问删除一条边形成两棵子树,两棵子树有多少种颜色是有 ...
- dsu on tree 树上启发式合并 学习笔记
近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数) ...
- dsu on tree[树上启发式合并学习笔记]
dsu on tree 本质上是一个 启发式合并 复杂度 \(O(n\log n)\) 不支持修改 只能支持子树统计 不能支持链上统计- 先跑一遍树剖的dfs1 搞出来轻重儿子- 求每个节点的子树上有 ...
- dsu on tree (树上启发式合并) 详解
一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...
- AGC 014E.Blue and Red Tree(思路 启发式合并)
题目链接 \(Description\) 给定两棵\(n\)个点的树,分别是由\(n-1\)条蓝边和\(n-1\)条红边组成的树.求\(n-1\)次操作后,能否把蓝树变成红树. 每次操作是,选择当前树 ...
- dsu on tree(树上启发式合并)
简介 对于一颗静态树,O(nlogn)时间内处理子树的统计问题.是一种优雅的暴力. 算法思想 很显然,朴素做法下,对于每颗子树对其进行统计的时间复杂度是平方级别的.考虑对树进行一个重链剖分.虽然都基于 ...
- CSU 1811: Tree Intersection(线段树启发式合并||map启发式合并)
http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1811 题意:给出一棵树,每一个结点有一个颜色,然后依次删除树边,问每次删除树边之后,分开的两个 ...
- codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(启发式合并)
codeforces 741D Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...
- 树上启发式合并(dsu on tree)学习笔记
有丶难,学到自闭 参考的文章: zcysky:[学习笔记]dsu on tree Arpa:[Tutorial] Sack (dsu on tree) 先康一康模板题吧:CF 600E($Lomsat ...
随机推荐
- Github PageHelper 原理解析
任何服务对数据库的日常操作,都离不开增删改查.如果一次查询的纪录很多,那我们必须采用分页的方式.对于一个Springboot项目,访问和查询MySQL数据库,持久化框架可以使用MyBatis,分页工具 ...
- Python日志模块logging简介
日志处理是项目的必备功能,配置合理的日志,可以帮助我们了解系统的运行状况.定位位置,辅助数据分析技术,还可以挖掘出一些额外的系统信息. 本文介绍Python内置的日志处理模块logging的常见用法. ...
- 领扣(LeetCode)错误的集合 个人题解
集合 S 包含从1到 n 的整数.不幸的是,因为数据错误,导致集合里面某一个元素复制了成了集合里面的另外一个元素的值,导致集合丢失了一个整数并且有一个元素重复. 给定一个数组 nums 代表了集合 S ...
- 0MQ宗旨
先来看<Implementing distributed applications with 0MQ and some other bad guys...>.用0MQ去实现分布应用,或者用 ...
- uniapp打包Android APP
1.uniAPP 将项目打包成,打包成功后格式如下 2.下载相关工具 Android studio(打包成app的工具) 和Hbuilder官方SDK,安装解压响应工具 3. 用 Android st ...
- Python拼接字符串的七种方式
忘了在哪看到一位编程大牛调侃,他说程序员每天就做两件事,其中之一就是处理字符串.相信不少同学会有同感. 几乎任何一种编程语言,都把字符串列为最基础和不可或缺的数据类型.而拼接字符串是必备的一种技能.今 ...
- iOS开发调试概览
概述 我们都知道Xcode默认的调试器是LLDB(在此之前使用的是GDB),但是关于LLDB的debug技巧并非所有人都比较清楚,可能所有人都知道p或者po命令打印一些变量.但是实际的情况时这些还远远 ...
- OpenStack集成ceph
openstack组件集成ceph OpenStack集成ceph详细过程可以查看ceph官方文档:ceph document OpenStack Queens版本,1台控制节点controller, ...
- PythonI/O进阶学习笔记_7.python动态属性,__new__和__init__和元类编程(上)
content: 上: 1.property动态属性 2.__getattr__和__setattr__的区别和在属性查找中的作用 3.属性描述符 和属性查找过程 4.__new__和__init__ ...
- 为宇宙第一强的IDE干一票
背景 在博客园看到很多人说.net在国内已死,很多人在为.net前途担忧,包括一些创业大佬也提及到这些问题,提及到客户指定了说使用php或者java. 那么基本可以确认了,.net 处于风雨漂泊的地位 ...