Gym-101615D Rainbow Roads 树的DFS序 差分数组
题目链接:https://cn.vjudge.net/problem/Gym-101615D
题意
给一棵树,每个边权表示一种颜色。
现定义一条彩虹路是每个颜色不相邻的路。
一个好点是所有从该节点开始的所有简单路径(最短路)都是彩虹路。
问有哪几个好点?按编号输出。
思路
按节点遍历,若有多条路边权一样,则这几个子树都不是好点。
除去不好点,剩下即为好点。
一开始的思路是树上dp,然而情况实在太多,WA好几次。
最后看题解,发现有个dfs序的操作,把子树表示成数组里的一个范围,每次区间打标志即可(差分数组)。
提交过程
| WA×n | 树形dp |
| AC |
代码
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=5e4+20, maxm=maxn*2;
struct Edge{
int to, nxt, val;
Edge(int to=0, int nxt=0, int val=0):
to(to), nxt(nxt), val(val) {}
}edges[maxm];
int head[maxn], esize;
int tim, st[maxn], siz[maxn], fa[maxn], dfn[maxn];
int n;
void init(void){
memset(head, -1, sizeof(head));
esize=0, tim=0;
}
void addEdge(int from, int to, int val){
edges[esize]=Edge(to, head[from], val);
head[from]=esize++;
}
void dfs(int u, int pre){
dfn[tim]=u;
st[u]=tim++; siz[u]=1; fa[u]=pre;
#define TO edges[i].to
for (int i=head[u]; i!=-1; i=edges[i].nxt)
if (TO!=pre) dfs(TO, u), siz[u]+=siz[TO];
#undef TO
}
int main(void){
int a, b, val;
while (scanf("%d", &n)==1){
init();
for (int i=0; i<n-1; i++){
scanf("%d%d%d", &a, &b, &val);
addEdge(a, b, val);
addEdge(b, a, val);
}
dfs(1, -1);
int diff[maxn]={0};
for (int u=1; u<=n; u++){
vector<pair<int, int> > e;
for (int i=head[u]; i!=-1; i=edges[i].nxt)
e.push_back(make_pair(edges[i].val, edges[i].to));
sort(e.begin(), e.end());
int ptr=0, sizes=e.size();
while (ptr<sizes){
int pre=e[ptr].first, tmp=ptr+1;
while (tmp<sizes && pre==e[tmp].first) tmp++;
if (tmp-1==ptr) {ptr++; continue;}
if (pre!=e[tmp-1].first) break;
for (; ptr<=tmp-1; ptr++){
int to=e[ptr].second;
// printf("%d: %d st%d siz%d\n", u, to, st[to], siz[to]);
if (to==fa[u]){
diff[st[1]]++;
diff[st[u]]--;
diff[st[u]+siz[u]]++;
}else{
diff[st[to]]++;
diff[st[to]+siz[to]]--;
}
}
}
}
for (int i=1; i<=n; i++)
diff[i]+=diff[i-1];
int ans[maxn], asize=0;
for (int i=1; i<=n; i++)
if (diff[st[i]]==0) ans[asize++]=i;
// for (int i=1; i<=n; i++)
// printf("%d: %d siz%d\n", i, st[i], siz[i]);
printf("%d\n", asize);
for (int i=0; i<asize; i++)
printf("%d\n", ans[i]);
}
return 0;
}
| Time | Memory | Length | Lang | Submitted |
|---|---|---|---|---|
| 62ms | 4876kB | 2466 | GNU G++ 5.1.0 | 2018-08-30 20:57:26 |
Gym-101615D Rainbow Roads 树的DFS序 差分数组的更多相关文章
- [2]树的DFS序
定义: 树的DFS序就是在对树进行DFS的时候,对树的节点进行重新编号:DFS序有一个很强的性质: 一颗子树的所有节点在DFS序内是连续的一段, 利用这个性质我们可以解决很多问题. 代码: void ...
- 树的dfs序 && 系统栈 && c++ rope
利用树的dfs序解决问题: 就是dfs的时候记录每个节点的进入时间和离开时间,这样一个完整的区间就是一颗完整的树,就转化成了区间维护的问题. 比如hdu3887 本质上是一个求子树和的问题 #incl ...
- CF877E Danil and a Part-time Job 线段树维护dfs序
\(\color{#0066ff}{题目描述}\) 有一棵 n 个点的树,根结点为 1 号点,每个点的权值都是 1 或 0 共有 m 次操作,操作分为两种 get 询问一个点 x 的子树里有多少个 1 ...
- HDU4117 GRE WORDS(AC自动机+线段树维护fail树的dfs序)
Recently George is preparing for the Graduate Record Examinations (GRE for short). Obviously the mos ...
- 【枚举】【DFS序】Gym - 101617G - Rainbow Roads
题意:一颗树,每条边有个颜色,一条路径被定义为“彩虹”,当且仅当其上没有长度大于等于2的同色子路径.一个结点被定义为“超级结点”,当且仅当从其发出的所有路径都是“彩虹”. 枚举所有长度为2,且同色的路 ...
- bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)
Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...
- 2018.11.01 NOIP训练 图论(线段树+倍增+dfs序)
传送门 一道挺妙的题. 对于询问点(u,v),如右图所示,我们可以发现存在一个点m在u->v的路径中,m子树的点到u是最近的,m子树外到v是最近的.其中dis(u,m)=(dis(u,v)-1) ...
- 线段树(dfs序建树加区间更新和单点查询)
题目链接:https://cn.vjudge.net/contest/66989#problem/J 记录一下这道折磨了我一天的题,.... 具体思路: 具体关系可通过dfs序建树,但是注意,在更新以 ...
- bzoj3306: 树(dfs序+倍增+线段树)
比较傻逼的一道题... 显然求子树最小值就是求出dfs序用线段树维护嘛 换根的时候树的形态不会改变,所以我们可以根据相对于根的位置分类讨论. 如果询问的x是根就直接输出整棵树的最小值. 如果询问的x是 ...
随机推荐
- Eclipse安装Jetty插件(Web容器)
Eclipse除了安装Tomcat插件外,还可以安装Jetty,相对来说Jetty比Tomcat配置简单. Tomcat安装及配置:http://www.cnblogs.com/EasonJim/p/ ...
- uva 10479(找规律+递归)
题意:有一个初始序列第一个数字是0. 规律是把前一次推出来的每个数字x.先接x个0,然后接x+1. 0 –> 1 –> 02 –> 1003 –> 02110004 那么这个序 ...
- phonegap(cordova) 自己定义插件代码篇(四)----读取本地图片
有时候确实知道本地图片地址,要获取到base64 /** * 获取本地图片,包括路径和压缩后的 base64 */ (function (cordova) { var define = cordov ...
- 远程桌面授权server没有提供许可证问题解决方法
今天远程server报如图所看到的错误,网上查找的方法 方法一:(亲測有效) mstsc /V:192.168.0.3 /admin 方法二:(因为server正在使用中,未作測试) 删除远程桌面服 ...
- VC++玩转Native Wifi API 2---Wifi on与wifi off
有心栽花花不开,无心插柳柳成排. 今天要说的这个wifi on\off是在软件层面控制无线网卡的开和关. 问题听起来简单,调查起来复杂.但解决起来却也简单.关键函数便是Native wifi a ...
- 【Oracle】RAC删除节点
环境: OS:OEL5.6 RAC:10.2.0.1.0 眼下有rac1.rac2.rac3三个节点,下面是删除rac3节点的具体过程 1.删除rac3节点上的数据库实例 [oracle@rac1 ~ ...
- 【SCOI 2005】 骑士精神
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1085 [算法] IDA* [代码] #include<bits/stdc++. ...
- 6.11Realm简介
CasRealm 统一认证授权中心 跟单点登录有关的.IniRealm 静态文件
- 彻底弄懂px em rem
国内的设计师大都喜欢用px,而国外的网站大都喜欢用em和rem,那么三者有什么区别,又各自有什么优劣呢? PX特点 1. IE无法调整那些使用px作为单位的字体大小: 2. 国外的大部分网站能够调整的 ...
- Hadoop MapReduce编程 API入门系列之wordcount版本5(九)
这篇博客,给大家,体会不一样的版本编程. 代码 package zhouls.bigdata.myMapReduce.wordcount1; import java.io.IOException; i ...