Gym - 101615 D Rainbow Roads dfs序
题目大意:
给出一颗树,每条边都有一个颜色,对一个点来说,如果其他所有点到这个点的简单路径,相连的边颜色都不同,这个点即合法点,统计所有的合法点。
思路:
对于一个节点来说
1、如果这个节点的两个子节点的边颜色一样,那么这两个子节点的子树都要放弃。
2、如果这个节点的子节点和他的父节点的边的颜色一样,那么子节点所在子树放弃,父节点中除了这个节点以外的其他节点都要放弃。
剩下的点就是合法点。
那怎么做到放弃呢?
先dfs处理出每个节点的dfs序,每个dfs序对应的节点标号,每个节点的子树大小(包括本身),对于第一种情况来说,dfs序在 子树节点dfs序 到 子树节点dfs序加上子树大小 这个左闭右开的区间都要放弃,则用一个数组,左边界加一,右边界减一。
对于第二种情况,放弃的子节点和上述一样处理,父节点就要放弃 dfs序从1到父节点dfs序,父节点dfs序+1到最后所有的点,则对应位置加一或者减一,最后vis[ i ]=vis[ i -1 ] + arr[ i ].处理完后,vis还等于0的点,就是合法的dfs序,找到这个dfs序对应的节点就可以了(dfs的时候就记录过了,大佬说这个做法叫差分约束)。
这题五万个点,每个点三个数据,用读入优化居然没有快,,,可能是我的读入优化还不够优秀吧。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string.h>
#include<sstream>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
#define CLR(a,b) memset((a),(b),sizeof((a)))
using namespace std;
typedef long long ll;
inline int rd() {
int f = 1; int x = 0; char s = getchar();
while (s<'0' || s>'9') { if (s == '-')f = -1; s = getchar(); }
while (s >= '0'&&s <= '9') { x = x * 10 + s - '0'; s = getchar(); }x *= f;
return x;
}
int n;
struct edge {
int v, color;
edge(){}
edge(int v,int color): v(v),color(color){} };
bool cmp(edge &a, edge &b)
{
return a.color < b.color;
}
const int maxn = 50010;
vector<edge >g[maxn];
int arr[maxn], fa[maxn], son[maxn], dfn[maxn],tot,cnt,vis[maxn],dir[maxn];
void dfs(int u, int pre)
{
fa[u] = pre;
son[u] = 1;
dfn[u] = ++cnt;
dir[cnt] = u;
for (auto it : g[u])
{
if (it.v == pre)continue;
dfs(it.v, u);
son[u] += son[it.v];
}
}
int main() {
cin >> n;
for (int i = 1; i < n; i++)
{
int u, v, color;
u = rd(), v = rd(), color = rd();
//scanf("%d%d%d", &u, &v, &color);
g[u].push_back(edge(v, color));
g[v].push_back(edge(u, color));
}
dfs(1, 0);
for (int i = 1; i <= n; i++)
{
sort(g[i].begin(), g[i].end(), cmp);
int si = g[i].size();
for (int j = 0; j < si - 1; j++)
{
if (g[i][j].color == g[i][j + 1].color)
{ int x = g[i][j].v, y = g[i][j+1].v;
if (fa[x] == i && fa[y] == i)
{ arr[dfn[x]]++;
arr[dfn[x] + son[x]]--;
arr[dfn[y]]++;
arr[dfn[y] + son[y]]--;
}
else if (fa[x] == i && fa[i] == y)
{ arr[dfn[x]]++;
arr[dfn[x] + son[x]]--;
arr[dfn[1]]++;
arr[dfn[i]]--;
arr[dfn[i] + son[i]]++;
}
else if (fa[y] == i && fa[i] == x)
{
swap(x, y);
arr[dfn[x]]++;
arr[dfn[x] + son[x]]--;
arr[dfn[1]]++;
arr[dfn[i]]--;
arr[dfn[i] + son[i]]++;
}
}
}
}
for (int i = 1; i <= n; i++)
{
vis[i] = vis[i - 1] + arr[i];
}
vector<int >ans;
for (int i = 1; i <= n; i++)
{
if (vis[i] == 0)
{
tot++;
ans.push_back(dir[i]);
}
}
printf("%d\n", tot);
sort(ans.begin(), ans.end());
for (auto it : ans)
{
printf("%d\n", it);
}
}
Gym - 101615 D Rainbow Roads dfs序的更多相关文章
- Gym - 101875I I Will Go (dfs序)
题意:N个人要参加一个局,每个人有自己的好朋友,如果他的好朋友来,他才有可能来.N个人的关系不够成环.Q次查询,问若x来了,y是否肯定来. 分析:若点y是x的祖先,则y肯定回来.一次dfs确定每个点覆 ...
- 【枚举】【DFS序】Gym - 101617G - Rainbow Roads
题意:一颗树,每条边有个颜色,一条路径被定义为“彩虹”,当且仅当其上没有长度大于等于2的同色子路径.一个结点被定义为“超级结点”,当且仅当从其发出的所有路径都是“彩虹”. 枚举所有长度为2,且同色的路 ...
- Gym-101615D Rainbow Roads 树的DFS序 差分数组
题目链接:https://cn.vjudge.net/problem/Gym-101615D 题意 给一棵树,每个边权表示一种颜色. 现定义一条彩虹路是每个颜色不相邻的路. 一个好点是所有从该节点开始 ...
- K. Random Numbers(Gym 101466K + 线段树 + dfs序 + 快速幂 + 唯一分解)
题目链接:http://codeforces.com/gym/101466/problem/K 题目: 题意: 给你一棵有n个节点的树,根节点始终为0,有两种操作: 1.RAND:查询以u为根节点的子 ...
- Codeforces Gym 101142 G Gangsters in Central City (lca+dfs序+树状数组+set)
题意: 树的根节点为水源,编号为 1 .给定编号为 2, 3, 4, …, n 的点的父节点.已知只有叶子节点都是房子. 有 q 个操作,每个操作可以是下列两者之一: + v ,表示编号为 v 的房子 ...
- Random Numbers Gym - 101466K dfs序+线段树
Tamref love random numbers, but he hates recurrent relations, Tamref thinks that mainstream random g ...
- Gym 101142G : Gangsters in Central City(DFS序+LCA+set)
题意:现在有一棵树,1号节点是水源,叶子节点是村庄,现在有些怪兽会占领一些村庄(即只占领叶子节点),现在要割去一些边,使得怪兽到不了水源.给出怪兽占领和离开的情况,现在要割每次回答最小的割,使得怪兽不 ...
- cdoj 574 High-level ancients dfs序+线段树
High-level ancients Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/s ...
- BZOJ 3011: [Usaco2012 Dec]Running Away From the Barn( dfs序 + 主席树 )
子树操作, dfs序即可.然后计算<=L就直接在可持久化线段树上查询 -------------------------------------------------------------- ...
随机推荐
- asp.net的验证码插件及方法、ashx验证码一般处理程序
需要引入一个ashx的一般处理程序! 把这个程序在前台当作一个图片使用就可以! 前台代码: <td> <img title="看不清?" style=" ...
- sed对指定行添加或删除注释
如下文本 zimu.txt aaaaa #bbbbbb cccccc dddddd 以下命令如果需要在文本中更改 需要加 -i 或者 -ri参数 用sed在aaa前加#注释 sed 's/^ ...
- 使用Eclipse的常见问题整理
我在Eclipse里新建一个android工程的时候附带着产生了一个名字为appcompat_v7的工程,这个工程是干什么用的啊?为何我新建的工程都出错了,错误信息提示为: error: Error ...
- 框架之 hibernate之各种查询
1. Hibernate的查询方式 2. Hibernate的查询策略 案例:使用Hibernate完成查询所有联系人功能 需求分析 1. 完成所有的联系人的查询 技术分析之Hibernate框架的查 ...
- Absolute Layout
----------------siwuxie095 根面板 contentPane 的默认布局为 Border Layout,将其 切换为 Absolute Layout Absolute Layo ...
- php环境引起的"syntax error unexpected $end"
今天在网上淘了一段php和javascript的二级联动下拉菜单的代码.本地运行的时候,一直提示错误 syntax error unexpected $end 本来还以为是括号或者标签没有用好,但是仔 ...
- [转载]HTTP的无状态是什么意思?
文章地址:https://www.cnblogs.com/bellkosmos/p/5237146.html#commentform 作者:赛艇队长 引子: 最近在好好了解http,发现对介绍http ...
- Linux问题FAQ1
1.使用vi编辑器时候,按方向键会产生A,B,C之类的 解决办法:ubuntu server 8.04, vim版本为 7.1.138,客户端使用pietty.vim 在插入模式下, 方向键被转为A ...
- 《Head First Servlets & JSP》-8-无脚本的JSP
以前servlet和JSP交互的代码 servlet代码示例: JSP代码示例: 若属性不是一个String而是一个Bean呢? 一个简单的JavaBean servlet代码示例: JSP代码示例: ...
- C++ string操作(转载)
1.string类的构造函数 string(const char * s); //用s字符串初始化 string(const string &s);//用string类的s初始化 string ...