Problem 魔法森林 (NOI2014)

题目大意

  给n个点,m条边的无向图,每条边有两个权值a,b。

  求一条从1-->n的路径,使得这条路径上max(a)+max(b)最小。输出最小值即可。

解题分析

  将边按照权值a从小到大排序后,依次加边,用lct维护一棵权值b组成的最小生成树。

  具体做法是如果所加边u-->v导致形成了一个环,那么比较一下u-->v路径中的最大值和这条边的b权值大小,来决定取那条边。

  处理边权的一个做法,将每条边看成一个新的点,向其两端的点连边。

参考程序

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std; #define N 200008
#define E 400008
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define clr(x,v) memset(x,v,sizeof(x));
#define bitcnt(x) __builtin_popcount(x)
#define rep(x,y,z) for (int x=y;x<=z;x++)
#define repd(x,y,z) for (int x=y;x>=z;x--)
const int mo = ;
const int inf = 0x3f3f3f3f;
const int INF = ;
/**************************************************************************/
int n,m;
int fa[N],val[N],mx[N],rev[N],c[N][],st[N]; struct line{
int u,v,a,b;
bool operator < (const line &k) const{
return a<k.a;
}
}eg[E];
bool isroot(int k){
return c[fa[k]][]!=k && c[fa[k]][]!=k;
}
void pushup(int x){
int l=c[x][],r=c[x][];
mx[x]=x;
if (val[mx[l]]>val[mx[x]]) mx[x]=mx[l];
if (val[mx[r]]>val[mx[x]]) mx[x]=mx[r];
}
void pushdown(int x){
int l=c[x][],r=c[x][];
if (rev[x]){
if (l) rev[l]^=;
if (r) rev[r]^=;
rev[x]^=;
swap(c[x][],c[x][]);
}
}
void rotate(int x){
int y=fa[x],z=fa[y],l,r;
if (c[y][]==x) l=; else l=; r=l^;
if (!isroot(y)){
if (c[z][]==y) c[z][]=x; else c[z][]=x;
}
fa[x]=z; fa[y]=x; fa[c[x][r]]=y;
c[y][l]=c[x][r]; c[x][r]=y;
pushup(y); pushup(x);
}
void splay(int x){
int top=; st[++top]=x;
for (int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
while (top) pushdown(st[top--]);
while (!isroot(x)){
int y=fa[x],z=fa[y];
if (!isroot(y)){
if (c[y][]==x^c[z][]==y) rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x){
int t=;
while (x){
splay(x);
c[x][]=t;
pushup(x);
t=x; x=fa[x];
}
}
void rever(int x){
access(x); splay(x); rev[x]^=;
}
void link(int u,int v){
rever(u); fa[u]=v;
}
void cut(int u,int v){
rever(u); access(v); splay(v); fa[c[v][]]=; c[v][]=; pushup(v);
}
int find(int u){
access(u); splay(u);
while (c[u][]) u=c[u][];
return u;
}
int query(int u,int v){
rever(u); access(v); splay(v); return mx[v];
} int main(){
scanf("%d%d",&n,&m);
rep(i,,m) scanf("%d%d%d%d",&eg[i].u,&eg[i].v,&eg[i].a,&eg[i].b);
sort(eg+,eg+m+);
int ans=INF;
rep(i,,m){
int u=eg[i].u,v=eg[i].v,a=eg[i].a,b=eg[i].b;
int flag=;
if (find(u)==find(v)){
int t=query(u,v);
if (b<val[t]){
cut(t,eg[t-n].u);
cut(t,eg[t-n].v);
}
else flag=;
}
if (flag) {
val[i+n]=b; mx[n+i]=n+i;
link(i+n,u);
link(i+n,v);
}
if (find()==find(n)){
int t=query(,n);
ans=min(ans,val[t]+a);
}
}
printf("%d\n",ans==INF?-:ans);
}

BZOJ3669 (动态树)的更多相关文章

  1. 动态树(Link-Cut-Tree)简单总结(指针版本)

    Link-Cut-Tree(动态树 LCT) 1.定义 1. 偏爱子节点: 一颗子树内最后访问的点若在该子树根节点 X 的某个儿子节点 P 的子树中,则称 P 为 X 的偏爱子节点. 偏爱边:连向偏爱 ...

  2. 如何利用FineReport制作动态树报表

    在对数据字段进行分类管理时,利用动态树折叠数据是一个很好的方法,也就是点击数据前面的加号才展开对应下面的数据,如下图.那这样的效果在制作报表时该如何实现呢? 下面以报表工具FineReport为例介绍 ...

  3. 动态树之LCT(link-cut tree)讲解

    动态树是一类要求维护森林的连通性的题的总称,这类问题要求维护某个点到根的某些数据,支持树的切分,合并,以及对子树的某些操作.其中解决这一问题的某些简化版(不包括对子树的操作)的基础数据结构就是LCT( ...

  4. 【BZOJ-3589】动态树 树链剖分 + 线段树 + 线段覆盖(特殊的技巧)

    3589: 动态树 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 405  Solved: 137[Submit][Status][Discuss] ...

  5. BZOJ-2049 Cave洞穴勘测 动态树Link-Cut-Tree (并查集骗分TAT)

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 5833 Solved: 2666 [Submit] ...

  6. 学习笔记-动态树Link-Cut-Tree

    --少年你有梦想吗? --少年你听说过安利吗? 安利一个集训队讲解:http://wenku.baidu.com/view/75906f160b4e767f5acfcedb 关于动态树问题,有多种方法 ...

  7. BZOJ 3589 动态树(子树操作,链查询)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3589 题意:给出一棵有根树,两种操作:(1)以u为根的子树所有节点权值加上一个数字 ...

  8. Tsinsen A1517. 动态树 树链剖分,线段树,子树操作

    题目 : http://www.tsinsen.com/A1517 A1517. 动态树 时间限制:3.0s   内存限制:1.0GB    总提交次数:227   AC次数:67   平均分:49. ...

  9. 动态树 Link-Cut Trees

    动态树 动态树问题, 即要求我们维护一个由若干棵子结点无序的有根树组成的森林. 要求这个数据结构支持对树的分割.合并,对某个点到它的根的路径的某些操作,以及对某个点的子树进行的某些操作. 在这里我们考 ...

  10. bzoj 2594: [Wc2006]水管局长数据加强版 动态树

    2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec  Memory Limit: 128 MBSubmit: 934  Solved: 291[Submit][Sta ...

随机推荐

  1. YY前端课程5-6

    第五次课内容: 1. 要注意标签的层次,运用缩进indent,使HTML结构清晰,增加可读性accessible 2. HTML布局网页,CSS显示样式(CSS是用来美化HTML标签的) 3. 开放标 ...

  2. Selenium VS QTP

      Selenium系列 QTP 适用结构  B/S结构  C/S.B/S结构 适用人员 有一定代码基础(Java.C#.Python.Ruby) 对编程不是很熟悉的.厌烦了做手工功能测试的.想快速进 ...

  3. SpringMVC Model

    处理模型数据 ModelAndView:处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据. @ModelAttribute:方法入参标注了该注解后,入参对象会放到数据模 ...

  4. ElasticSearch配置说明

    配置文件位于%ES_HOME%/config/elasticsearch.yml文件中. cluster.name: elasticsearch 配置集群名称,默认elasticsearch node ...

  5. js正则表达式大全(2)

    在JAVASCRIPT里面判断一个字符串是否是电子邮件的格式: if(formname.email.value!=formname.email.value.match(/^\w +[@]\w +[.] ...

  6. web前端面试题

    HTML+CSS 1.对WEB标准以及W3C的理解与认识 标签闭合.标签小写.不乱嵌套.提高搜索机器人搜索几率.使用外链css和js脚本.结构行为表现的分离.文件下载与页面速度更快.内容能被更多的用户 ...

  7. 使用php-cs-fixer格式化你的代码

    在开发中,我们会有意识的遵行一套规范来保证团队代码的一致性.PSR是我们PHP遵循的共同规范. 在这里,推荐一个代码格式化工具php-cs-fixer,可以一键把代码格式化为PSR-2的标准. 安装: ...

  8. Maven搭建SSH环境

    一.新建maven项目 选中maven-aechetype-webapp group Id一般为公司域 :Artifact Id相当于项目名称 :version不需要更改:Package不使用默认,手 ...

  9. Calculator(1.5)

    Calculator(1.5) Github链接 ps.负数的处理未完成 解题过程中遇到的困难和解决 <stack>的使用: 认真研究了栈,基本上掌握了用法,与<queue>的 ...

  10. [转]SPICE仿真软件基础(整理)

    现在常用的SPICE仿真软件为方便用户使用都提供了较好的用户界面,在用仿真库中的元器件连成原理图后就可以进行仿真(当然要设置必要的仿真参数),但实际上只是用原理图自动产生了SPICE的格式语句,还是要 ...