51nod1307(暴力树剖/二分&dfs/并查集)
题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1307
题意: 中文题诶~
思路:
解法1:暴力树剖
用一个数组 num[i] 维护编号为 i 的边当前最大能承受的重量. 在加边的过程中根据给出的父亲节点将当前边所在的链上所有边的num都减去当前加的边的重量, 注意当前边也要减自重. 那么当num首次出现负数时加的边号即位答案;
事实上这个算法的时间复杂度是O(n^2)的, 不过本题并没有出那种退化成单链的数据, 所以直接暴力也能水过;
代码:
#include <iostream>
#include <stdio.h>
using namespace std; const int MAXN = 5e4 + ;
struct node{
int c, w, pre;
}gel[MAXN];
int num[MAXN];//num[i]为编号为i的绳子当前可以承受的最大重量 int main(void){
int n, ans = -;
scanf("%d", &n);
for(int i = ; i < n; i++){
scanf("%d%d%d", &gel[i].c, &gel[i].w, &gel[i].pre);
if(ans != -) continue;
num[i] = gel[i].c;
int cnt = i;
while(cnt != -){
num[cnt] -= gel[i].w;
if(ans == - && num[cnt] <= -) ans = i;
cnt = gel[cnt].pre;//指向cnt的父亲节点
}
}
if(ans == -) cout << n << endl;
else cout << ans << endl;
return ;
}
解法2: 二分 + dfs
很显然在加边的过程中所有边的承受重量都是单调不减的, 那么可以考虑二分答案. 不过要注意判断函数的写法, 每一次判断都需要判断当前 mid条 边组成的树的所有边, 而不能只判断当前 mid 所在链上的边, 显然其他链上也可能存在不合法的边. 判断所有边的话可以 dfs 一遍, 回溯时判断即可.
代码:
#include <iostream>
#include <stdio.h>
#include <vector>
#define ll long long
using namespace std; const int MAXN = 5e4 + ;
struct node{
int c, w, pre;
}gel[MAXN];
vector<int> sol[MAXN];
bool flag; ll dfs(int u, int x){
ll sum = gel[u].w;
if(u > x) return ;//mid边后面的不要算上去
for(int i = ; i < sol[u].size(); i++){
sum += dfs(sol[u][i], x);
}
if(sum > gel[u].c && u) flag = false;//0是一个虚根,并没有对应的边
return sum;
} int main(void){
int n;
scanf("%d", &n);
for(int i = ; i <= n; i++){
scanf("%d%d%d", &gel[i].c, &gel[i].w, &gel[i].pre);
gel[i].pre++;
sol[gel[i].pre].push_back(i);
}
int l = , r = n, cnt = n;
while(l <= r){
flag = true;
int mid = (l + r) >> ;
dfs(, mid);
if(flag) cnt = mid, l = mid + ;
else r = mid - ;
}
printf("%d\n", cnt);
}
解法3: 并查集
#include <iostream>
#include <stdio.h>
#include <vector>
#define ll long long
using namespace std; const int MAXN = 1e5 + ;
struct node{
ll c, w, p;
}gel[MAXN]; ll ww[MAXN];
vector<int> vt[MAXN];
int pre[MAXN], sol; int find(int x){
return pre[x] == x ? x : pre[x] = find(pre[x]);
} void update(int u){
for(int i = ; i < vt[u].size(); i++){
gel[u].w += gel[vt[u][i]].w;
pre[vt[u][i]] = u;
}
while(gel[u].w > gel[u].c){//u即为当前根节点
gel[find(sol)].w -= ww[sol];
sol--;
}
} int main(void){
int n;
scanf("%d", &n);
for(int i = ; i <= n; i++){
scanf("%lld%lld%lld", &gel[i].c, &gel[i].w, &gel[i].p);
gel[i].p++;
vt[gel[i].p].push_back(i);
ww[i] = gel[i].w;//后面会对gel操作,所以需要先记录下gel的初始值来
pre[i] = i;
}
sol = n;
for(int i = n; i > ; i--){
update(i);
}
printf("%d\n", sol);
return ;
}
51nod1307(暴力树剖/二分&dfs/并查集)的更多相关文章
- 【CF576E】Painting Edges 线段树按时间分治+并查集
[CF576E]Painting Edges 题意:给你一张n个点,m条边的无向图,每条边是k种颜色中的一种,满足所有颜色相同的边内部形成一个二分图.有q个询问,每次询问给出a,b代表将编号为a的边染 ...
- BZOJ_4025_二分图_线段树按时间分治+并查集
BZOJ_4025_二分图_线段树按时间分治+并查集 Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简 ...
- 【BZOJ1821】[JSOI2010]部落划分(二分,并查集)
[BZOJ1821][JSOI2010]部落划分(二分,并查集) 题面 BZOJ 洛谷 题解 二分答案,把距离小于二分值的点全部并起来,\(\mbox{check}\)一下是否有超过\(K\)个集合就 ...
- 洛谷P4145 上帝造题的七分钟2/花神游历各国 [树状数组,并查集]
题目传送门 题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是 ...
- 【bzoj3007】拯救小云公主 二分+对偶图+并查集
题目描述 英雄又即将踏上拯救公主的道路…… 这次的拯救目标是——爱和正义的小云公主. 英雄来到boss的洞穴门口,他一下子就懵了,因为面前不只是一只boss,而是上千只boss.当英雄意识到自己还是等 ...
- [HNOI2006]公路修建问题 (二分答案,并查集)
题目链接 Solution 二分答案+并查集. 由于考虑到是要求花费的最小值,直接考虑到二分. 然后对于每一个二分出来的答案,模拟 \(Kruskal\) 的过程再做一遍连边. 同时用并查集维护联通块 ...
- BZOJ 4034 [HAOI2015]树上操作 线段树+树剖或dfs
题意 直接照搬原题面 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所 ...
- CF 115 A 【求树最大深度/DFS/并查集】
CF A. Party time limit per test3 seconds memory limit per test256 megabytes inputstandard input outp ...
- hdu 5652 India and China Origins(二分+bfs || 并查集)BestCoder Round #77 (div.2)
题意: 给一个n*m的矩阵作为地图,0为通路,1为阻碍.只能向上下左右四个方向走.每一年会在一个通路上长出一个阻碍,求第几年最上面一行与最下面一行会被隔开. 输入: 首行一个整数t,表示共有t组数据. ...
随机推荐
- 分享知识-快乐自己:Liunx 安装 Zookeeper
Zookeeper可以安装在windows中也可以安装在linux中! 但是我们的服务器基本都是在linux之上 安装我们的 zookeeper 注册中心! 安装成功之后 修改 nat 模式对应的端 ...
- php 数据处理--合并,拆分,追加,去重
1. 合并数组 array_merge()函数将数组合并到一起,返回一个联合的数组.所得到的数组以第一个输入数组参数开始,按后面数组参数出现的顺序依次迫加. 示例代码: <?php $arr = ...
- ES doc_values介绍2——本质是field value的列存储,做聚合分析用,ES默认开启,会占用存储空间
一.doc_values介绍 doc values是一个我们再三重复的重要话题了,你是否意识到一些东西呢? 搜索时,我们需要一个“词”到“文档”列表的映射 排序时,我们需要一个“文档”到“词“列表的映 ...
- Pyton基础-base64加解密
base64加密后是可逆的,所以url中传输参数一般用base64加密 import base64 s='username=lanxia&username2=zdd' new_s=base64 ...
- python中的enumerate()函数用法
enumerate函数用于遍历序列中的元素以及它们的下标,可以非常方便的遍历元素. 比如我在往excel中写数据时就用到了这个函数: data = [] data.append(('预约码', '车牌 ...
- POJ-2564 01背包问题
#include"cstdio" #include"cstring" #include"algorithm" using namespace ...
- uoj problem 31 猪猪侠再战括号序列
题目大意: 给定一个长度为2n的括号序列.定义一个关于区间[l,r]的翻转操作为位置平移对调. 即翻转")))()("可以得到"()()))((" 用不超过n次 ...
- css 更换浏览器 默认图标
cursor:url("./images/test.cur"),auto; 只在chrome测试过...
- [转]Unity3D学习笔记(四)天空、光晕和迷雾
原文地址:http://bbs.9ria.com/thread-186942-1-1.html 作者:江湖风云 六年前第一次接触<魔兽世界>的时候,被其绚丽的画面所折服,一个叫做贫瘠之地的 ...
- unittest单元测试生成HTML测试报告
前言: HTMLTestRunner 是 Python 标准库的 unittest 模块的一个扩展,它可以生成 HTML的 测试报告. 一.下载HTMLTestRunnerNew.py文件: 下载链接 ...