BZOJ 3784: 树上的路径
Description
问一棵树上前 \(k\) 大路径的边权.
Sol
边分治.
非常感谢数据没有菊花图.
为了写写边分治试试然后就开了这道题.
边分治非常好想,选一条重边,分成两部分,然后分别求最大值,对每个重边建一个堆维护一下,全局堆里存答案.
rebuild好像写的有问题啊qwq...疯狂RE不止...最后不管了,直接不重建树也能A...
rebuild我就是想的将他建成二叉树的样子,每个点的度数不超过3或4差不多就可以了.
Code
/**************************************************************
Problem: 3784
User: BeiYu
Language: C++
Result: Accepted
Time:4540 ms
Memory:26660 kb
****************************************************************/ #include <bits/stdc++.h>
using namespace std; #define debug(a) cout<<#a<<"="<<a<<" "
#define mpr make_pair
typedef pair< int,int > pr;
typedef pair< int,pr > prr;
const int N = 100500; int n,k,rt,rtt;
int d[N],sz[N],ud[N];
int vis[N<<1]; int cnte;
struct Edge { int to,w; }edge[N<<2];
vector< int > g[N];
priority_queue< pr > qq;
priority_queue< pr > q[N];
vector< int > nxt[N];
vector< int > tmp[N][2]; inline int in(int x=0,char ch=getchar()) { while(ch>'9' || ch<'0') ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x; } void AddEdge(int fr,int to,int w) { g[fr].push_back(cnte);edge[cnte++]=(Edge){ to,w }; } void Print() {
cout<<"start"<<endl;
for(int i=1;i<=n;i++) {
cout<<i<<"-->";
for(int j=0;j<(int)g[i].size();j++) cout<<"id:"<<g[i][j]<<" "<<edge[g[i][j]].to<<" ";
cout<<endl;
}
cout<<"-------------------------"<<endl;
} void ReBuild(int u,int fa) {
int cnt=0,id=-1,lst=0,fst=0;
if(g[u].size()>3) for(int i=g[u].size()-1,v;i>=1;i--)
if((v=edge[g[u][i]].to)!=fa) {
if(cnt&1) {
g[n].push_back(g[u][i]);
}else {
g[++n].push_back(g[u][i]);
if(lst) {
AddEdge(lst,n,0);
AddEdge(n,lst,0);
}else {
fst=n;
}lst=n;
}
cnt^=1;
edge[g[u][i]^1].to=n;
g[u].pop_back();
}else id=g[u][i],g[u].pop_back();
if(id!=-1) g[u].push_back(id);
if(fst) AddEdge(u,fst,0),AddEdge(fst,u,0);
for(int i=0;i<(int)g[u].size();i++) if(edge[g[u][i]].to!=fa) ReBuild(edge[g[u][i]].to,u); } void GetSize(int u,int fa) {
d[u]=d[fa]+1,sz[u]=1;
for(int i=g[u].size()-1,v;~i;i--) if((v=edge[g[u][i]].to)!=fa && !vis[g[u][i]]) {
GetSize(v,u),sz[u]+=sz[v];
}
}
void GetRoot(int u,int nn) {
rt=-1,rtt=N;GetSize(u,u);
// for(int i=1;i<=n;i++) cout<<sz[i]<<" ";cout<<endl;
// for(int i=1;i<=n;i++) cout<<d[i]<<" ";cout<<endl;
queue< pr > q;q.push(mpr(u,u));
for(pr x;!q.empty();) {
x=q.front(),q.pop();
int u=x.first,tmp;
for(int i=0,v;i<(int)g[u].size();i++) if((v=edge[g[u][i]].to)!=x.second && !vis[g[u][i]]){
if(d[u]>d[v]) tmp=max(sz[u],nn-sz[u]);
else tmp=max(sz[v],nn-sz[v]);
// debug(u),debug(v),debug(tmp),debug(g[u][i])<<endl;
if(tmp<rtt) rtt=tmp,rt=g[u][i];
q.push(mpr(v,u));
}
}
// debug(u),debug(rt)<<endl;
}
void GetDep(int u,int fa,int w,vector< int > &vv) {
vv.push_back(w);
for(int i=0,v;i<(int)g[u].size();i++) if((v=edge[g[u][i]].to)!=fa && !vis[g[u][i]]) {
GetDep(v,u,w+edge[g[u][i]].w,vv);
}
} void GetAns(int x,int nn) {
vis[x]=vis[x^1]=1;
int u=edge[x].to,v=edge[x^1].to;
GetDep(u,u,0,tmp[x][0]),GetDep(v,v,0,tmp[x][1]); sort(tmp[x][0].begin(),tmp[x][0].end(),greater< int >());
sort(tmp[x][1].begin(),tmp[x][1].end(),greater< int >()); // cout<<"---------------------"<<endl;
// debug(x),debug(nn),debug(u),debug(v)<<endl;
// for(int i=0;i<(int)tmp[x][0].size();i++) cout<<tmp[x][0][i]<<" ";cout<<endl;
// for(int i=0;i<(int)tmp[x][1].size();i++) cout<<tmp[x][1][i]<<" ";cout<<endl; nxt[x].resize(tmp[x][0].size());
for(int i=0;i<(int)tmp[x][0].size();i++) nxt[x][i]=0; for(int i=0;i<(int)tmp[x][0].size();i++) q[x].push(mpr(tmp[x][0][i]+tmp[x][1][0]+edge[x].w,i)); // debug(tmp[x][0][i]+tmp[x][1][0]+edge[x].w)
// debug(q[x].top().first)<<endl;
qq.push(mpr(q[x].top().first,x)); if(d[u]<d[v]) swap(u,v);
int ss=sz[u];
GetRoot(u,ss);
if(rt!=-1) GetAns(rt,ss);
GetRoot(v,nn-ss);
if(rt!=-1) GetAns(rt,nn-ss);
}
void init() {
n=in(),k=in();
for(int i=1,u,v,w;i<n;i++)
u=in(),v=in(),w=in(),AddEdge(u,v,w),AddEdge(v,u,w); // ReBuild(1,1); // Print(); // cout<<"qwq"<<endl; GetRoot(1,n); // debug(rt)<<endl; GetAns(rt,n); }
void Del(int x) {
pr r=q[x].top();
q[x].pop();
int u=r.second;
if(nxt[x][u]+1<(int)tmp[x][1].size()) nxt[x][u]++,q[x].push(mpr(tmp[x][0][u]+tmp[x][1][nxt[x][u]]+edge[x].w,u));
qq.push(mpr(q[x].top().first,x));
}
int Query() {
pr x=qq.top();qq.pop();
int r=x.first,u=x.second;
Del(u); return r;
}
int main() {
// freopen("in.in","r",stdin);
// ios::sync_with_stdio(false);
init(); for(;k--;) {
printf("%d\n",Query());
} return 0;
}
BZOJ 3784: 树上的路径的更多相关文章
- bzoj 3784: 树上的路径 堆维护第k大
3784: 树上的路径 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 88 Solved: 27[Submit][Status][Discuss] ...
- BZOJ.3784.树上的路径(点分治 贪心 堆)
BZOJ \(Description\) 给定一棵\(n\)个点的带权树,求树上\(\frac{n\times(n-1)}{2}\)条路径中,长度最大的\(m\)条路径的长度. \(n\leq5000 ...
- bzoj 3784: 树上的路径【点分治+st表+堆】
参考:https://www.cnblogs.com/CQzhangyu/p/7071477.html 神奇的点分治序(或者叫点剖?).就是把点分治扫过的点依次放进队列里,然后发现,对于每一棵树摊到序 ...
- BZOJ 3784: 树上的路径 点分治+二分+set
很容易想出二分这个思路,但是要想办法去掉一个 $log$. 没错,空间换时间. 双指针的部分错了好几次~ Code: #include <set> #include <queue&g ...
- 【BZOJ-3784】树上的路径 点分治 + ST + 堆
3784: 树上的路径 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 462 Solved: 153[Submit][Status][Discuss ...
- 树上的路径 BZOJ 3784
树上的路径 [问题描述] 给定一个N个结点的树,结点用正整数1..N编号.每条边有一个正整数权值.用d(a,b)表示从结点a到结点b路边上经过边的权值.其中要求a<b.将这n*(n-1)/2个距 ...
- codevs 2756树上的路径
题意: 2756 树上的路径 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给出一棵树,求出最小的k,使得,且在树 ...
- BZOJ 2337 XOR和路径 | 高斯消元 期望 位运算
BZOJ 2337 XOR和路径 题解 这道题和游走那道题很像,但又不是完全相同. 因为异或,所以我们考虑拆位,分别考虑每一位: 设x[u]是从点u出发.到达点n时这一位异或和是1的概率. 对于所有这 ...
- 【BZOJ3784】树上的路径 点分治序+ST表
[BZOJ3784]树上的路径 Description 给定一个N个结点的树,结点用正整数1..N编号.每条边有一个正整数权值.用d(a,b)表示从结点a到结点b路边上经过边的权值.其中要求a< ...
随机推荐
- [LeetCode] Convert Sorted Array to Binary Search Tree 将有序数组转为二叉搜索树
Given an array where elements are sorted in ascending order, convert it to a height balanced BST. 这道 ...
- [LeetCode] Anagrams 错位词
Given an array of strings, return all groups of strings that are anagrams. Note: All inputs will be ...
- 通过源码了解ASP.NET MVC 几种Filter的执行过程
一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神的工作,而且很多人觉得平时根本不需要知道这些,会用就行了.其实阅读源 ...
- .NET程序员细数Oracle与众不同的那些奇葩点
扯淡 距上次接触 Oracle 数据库已经是 N 年前的事了,Oracle 的工作方式以及某些点很特别,那会就感觉,这货就是一个奇葩!最近重拾记忆,一直在折腾 Oracle,因为 Oracle 与众不 ...
- 【笔记】jstree插件的基本使用
官网地址:https://www.jstree.com/ json返回参数格式:推荐第二种方式 不需要在重新拼接返回格式 不刷新页面重新初始化 jstree时使用:$.jstree.destroy() ...
- 关于CAJViewer 无法获取document路径问题
修改注册表 进入注册表编辑器: win+R >>输入 regedit 如下图: 修改关键注册表项(两项相同值应同时修改) 1.HKEY_CURRENT_USER\Software\Mic ...
- Error Domain=NSURLErrorDomain Code=-999 “The operation couldn’t be completed.
转:http://www.wangzhengdong.com/blog/error-domainnsurlerrordomain-code-999-the-operation-couldnt-be-c ...
- AnjularJS系列3 —— 数据的双向绑定
第三篇,双向的数据绑定 数据绑定是AnguarJS的特性之一,避免书写大量的初始代码从而节约开发时间 数据绑定指令提供了你的Model投射到view的方法.这些投射可以无缝的,毫不影响的应用到web应 ...
- R for循环之break,next
next跳出本次循环 break跳出本层循环(当有多个for 循环时,即跳出最近的一个for循环)
- ROC & AUC笔记
易懂:http://alexkong.net/2013/06/introduction-to-auc-and-roc/ 分析全面但难懂:http://mlwiki.org/index.php/ROC_ ...