题目传送门(内部题15)


输入格式

第一行一个整数$n$,代表点数
接下来$n-1$行,每行三个数$x,y,z$,代表点$i$与$x$之间有一条边,若$y$为$0$代表初始为白色,否则为黑色,若$z$为$0$代表不对最终颜色做要求,否则代表要求为黑色。


输出格式

达到目的的最少操作多少次数。


样例

样例输入:

7
1 0 1
1 1 1
2 0 1
2 0 1
3 1 1
3 0 1

样例输出:

3


数据范围与提示

对于$30\%$的数据,所有的$x$等于$1$。
对于$70\%$的数据,所有边最终都必须为黑色
对于$100\%$的数据,$n\leqslant 1,000,000$。


题解

先看数据范围,$n\leqslant 1,000,000$(注意是一百万,不是十万,可能只有我数不清几个$0$了吧?),这只能允许我们$\Theta(n)$。

$70\%$算法:

还是先从部分分下手,先来考虑$70\%$的数据,所有便最终都必须为黑色,考虑贪心。

比方说有下面这样一条链:

我们可以选择翻转$1\sim 3$和$4\sim 5$,也可以选择先翻转$1\sim 5$再将$3\sim 4$翻转回来,但是都需要两步,所以我们可以贪心的扫每一条链,直到扫到一条黑边为止,把这中间的都翻转即可。

那么现在来考虑许多边连向一个点的情况:

比方说上面这张图,一共有三个白边连向点$1$,你可能首先会下意识的以为需要翻转三次(聪明的你也可能没有),但是仔细一想,我们可以把这其中任意两个翻转合并,如翻转$2\sim 1\sim 4$这条路径,然后再翻转$1\sim 7$这条路径以达到目的。

那么不妨这样讲,对于多条边连向一个点的情况,其所需的翻转次数即为$\left \lceil \frac{黑边个数}{2} \right \rceil$。

时间复杂度:$\Theta(n)$。

期望得分:$70$分。

实际得分:$60$分。

$100\%$算法:

显然对于一道$T1$来说,我们应该$A$掉它。

发现每条边只会被要求为黑色,或者是任意颜色,所以在来贪心。

对于任意颜色,我们可以无视它,这不太好想,但仔细一想也是对的,我也不知道该怎么解释了,自己体会吧?所以我们可以把这种边缩掉,我的方法是用一个类似并查集思想的东西,但是比并查集简单的多。

时间复杂度:$\Theta(n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct rec{int nxt,to,w;}e[2000001];
int head[1000001],cnt=1;
int n;
bool vis[2000001];
int fa[1000001];
int ans;
void add(int x,int y,int w)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
e[cnt].w=w;
head[x]=cnt;
}
void dfs(int x)
{
for(int i=head[x];i;i=e[i].nxt)
if(!vis[i]&&!e[i].w)
{
vis[i]=vis[i^1]=1;
dfs(e[i].to);
return;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=2;i<=n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if(!z)fa[i]=fa[x];
else
{
add(i,fa[x],y);
add(fa[x],i,y);
}
}
for(int x=1;x<=n;x++)
{
int sum=0;
for(int i=head[x];i;i=e[i].nxt)
if(!vis[i]&&!e[i].w)
{
vis[i]=vis[i^1]=1;
dfs(e[i].to);
sum++;
}
if(sum&1)ans+=sum/2+1;
else ans+=sum/2;
}
printf("%d",ans);
return 0;
}

rp++

[CSP-S模拟测试]:虎(DFS+贪心)的更多相关文章

  1. [CSP-S模拟测试]:Blue(贪心)

    题目描述 $Blue$是个动物学家,不仅喜欢研究猫和老鼠,还喜欢研究青蛙.他最近开始研究青蛙过河的问题,可以简化成:数轴上$0$为岸边,$L$为河对岸.$(0,L)$中间存在$n$个石子.已知青蛙一跳 ...

  2. [CSP-S模拟测试]:爬(贪心)

    题目传送门(内部题134) 输入格式 第一行两个数$N,L$. 接下来$N$行每行两个数$A_i,B_i$. 接下来$N$行每行一个整数$C_i$. 输出格式 一行一个整数表示答案,无解输出$-1$. ...

  3. [CSP-S模拟测试]:午餐(贪心+最短路)

    题目传送门(内部题115) 输入格式 第一行两个正整数$n,m$. 接下来$m$行,每行$4$个正整数$u_j,v_j,L_j,R_j$. 接下来一行$n$个数,若第$i$个数为$1$,则$i$号同学 ...

  4. [CSP-S模拟测试]:格式化(贪心)

    题目传送门(内部题105) 输入格式 每组数据第一行一个正整数$n$,表示硬盘块数,接下来$n$行,每行两个正整数,第一个正整数为硬盘格式化前的容量,第二个正整数为格式化之后的容量. 输出格式 对每组 ...

  5. [CSP-S模拟测试]:优化(贪心+DP)

    题目描述 $visit\text{_}world$发现有下优化问题可以用很平凡的技巧解决,所以他给你分享了这样一道题:现在有长度为$N$的整数序列$\{ a_i\}$,你需要从中选出$K$个不想叫的连 ...

  6. [CSP-S模拟测试]:梦境(贪心+小根堆)

    题目描述 智者奥尔曼曾说过:有缘的人即使相隔海角天涯,也会在梦境中相遇. $IcePrince\text{_}1968$和$IcePrincess\text{_}1968$便是如此.有一天$IcePr ...

  7. [CSP-S模拟测试]:d(贪心+树状数组)

    题目传送门(内部题65) 输入格式 第一行,一个自然数$T$,代表数据组数.对于每组数据:第一行,一个正整数$n$,一个自然数$m$.接下来$n$行,每行两个正整数,$a_i,b_i$. 输出格式 对 ...

  8. [CSP-S模拟测试]:Tree(贪心)

    题目描述 给定一颗$n$个点的树,树边带权,试求一个排列$P$,使下式的值最大 $$\sum \limits_{i=1}^{n-1}maxflow(P_i,P_{i+1})$$ 其中$maxflow( ...

  9. [CSP-S模拟测试]:赛(贪心+三分)

    题目描述 由于出题人思维枯竭所以想不出好玩的背景.有$n$个物品,第$i$个物品的价格是$v_i$,有两个人,每个人都喜欢$n$个物品中的一些物品.要求选出正好$m$个物品,满足选出的物品中至少有$k ...

随机推荐

  1. 爬虫(十一)—— 请求库(三)pypeteer请求库

    曾经使用模拟浏览器操作(selenium + webdriver)来写爬虫,但是稍微有点反爬的网站都会对selenium和webdriver进行识别,网站只需要在前端js添加一下判断脚本,很容易就可以 ...

  2. 一个简单的winform程序调用webservices

    本文原创,如需转载,请标明源地址,谢谢合作!http://blog.csdn.net/sue_1989/article/details/6597078 本文的编写IDE为VSTS2008和.NET F ...

  3. 道路模型--linear-parabolic model

    读过很多道路追踪的论文,经常都需要道路模型的建模.我不知道是不是因为自己太笨还是怎样,好多人建的模型我实在无法理解他的用意何在,而且我真的深刻怀疑他们那些模型的参数是不是真的可以求出来.就比如这篇文章 ...

  4. node的fs模块使用————node

    node的fs模块使用----node fs模块是调用文件的模块. var fs=require('fs'); //引用模块. //查看文件信息 fs.stat('index.txt',functio ...

  5. Linux学习笔记之文件与文件系统的压缩与打包

    四.文件与文件系统的压缩与打包 用途: 传输时减少带宽 Linux系统常见的压缩命令 Compass(旧版压缩,并且在centOS中默认为不安装) gzip, zcat bzip2, bzcat zi ...

  6. linux ---JDK的安装与配置--两种方式

    linux下的JDK的安装与配置:JDK的安装有两种方式: tar包和rpm安装1.tar包安装: 下载地址:http://www.oracle.com/technetwork/java/javase ...

  7. Sass函数:数字函数-ceil()函数

    ceil() 函数将一个数转换成最接近于自己的整数,会将一个大于自身的任何小数转换成大于本身 1 的整数.也就是只做入,不做舍的计算: >> ceil(2.0) 2 >> ce ...

  8. java ArrayList存储基本类型

    package java06; /* 如果希望像集合ArrayList中存储基本数据类型数据,必须使用基本数据类型对应的“包装类” 基本数据类型 包装类(引用类型,包装类都位于java.lang包下 ...

  9. shell 单行多行注释

    1. 单行注释 众所周知,#  比如想要注释:echo “ni” # echo "ni" 2. 多行注释: 法一: : << ! 语句1 语句2 语句3 语句4 ! 法 ...

  10. 1、pip不是内部运行程序 解决方法

    一.方式一 1.切换到pip所在路径: shit+ 右键. 再此处打开运行窗口 2.执行 pip install pytest 脚本即可. 二.方式二,添加环境变量 1.将pip所在的文件路径 添加到 ...