3669 [Noi2014]魔法森林(LCT,最小生成树)
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=3669
【题意】
给定一个无向图,求1-n的路径中最小的max{ai}+max{bi}
【思路】
将边按照a排序。LCT维护关于b的最小生成树。
顺序枚举每条边u,v,如果u,v已经连接则比较u,v路径上的最大边与新边,否则直接相连。
如果1与n连通,则用e.a+max{e.b}更新ans。直观地看,最小生成树上的max{e.b}是1..i条边加入后能够得到的最小b。
_max的初值赋-1,即保证maxe存在,否则无限TLE
【代码】
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = 1e5+; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} struct Edge {
int u,v,a,b;
bool operator < (const Edge& rhs) const {
return a<rhs.a;
}
}e[N<<];
int en;
void adde(int u,int v,int a,int b)
{
e[++en]=(Edge){u,v,a,b};
} namespace LCT { struct Node {
int rev,v,maxe;
Node *ch[],*fa;
Node() {}
Node(int x) ;
void reverse() {
rev^=;
swap(ch[],ch[]);
}
void up_push() {
if(fa->ch[]==this||fa->ch[]==this)
fa->up_push();
if(rev) {
ch[]->reverse();
ch[]->reverse();
rev=;
}
}
void maintain() {
int _max=-;
if(e[ch[]->maxe].b>_max)
_max=e[ch[]->maxe].b,maxe=ch[]->maxe;
if(e[ch[]->maxe].b>_max)
_max=e[ch[]->maxe].b,maxe=ch[]->maxe;
if(e[v].b>_max) maxe=v;
}
} T[N<<],E[N<<],*null=&T[];
Node::Node(int x) {
ch[]=ch[]=fa=null;
rev=; v=maxe=x;
} void rot(Node* o,int d) {
Node *p=o->fa;
p->ch[d]=o->ch[d^];
o->ch[d^]->fa=p;
o->ch[d^]=p;
o->fa=p->fa;
if(p==p->fa->ch[])
p->fa->ch[]=o;
else if(p==p->fa->ch[])
p->fa->ch[]=o;
p->fa=o;
p->maintain();
}
void splay(Node* o) {
o->up_push();
Node* nf,*nff;
while(o->fa->ch[]==o||o->fa->ch[]==o) {
nf=o->fa,nff=nf->fa;
if(o==nf->ch[]) {
if(nf==nff->ch[]) rot(nf,);
rot(o,);
} else {
if(nf==nff->ch[]) rot(nf,);
rot(o,);
}
}
o->maintain();
}
void Access(Node *o) {
Node *son=null;
while(o!=null) {
splay(o);
o->ch[]=son;
o->maintain();
son=o; o=o->fa;
}
}
void evert(Node *o) {
Access(o);
splay(o);
o->reverse();
}
void Link(Node *u,Node *v) {
evert(u);
u->fa=v;
}
void Cut(Node *u,Node *v) {
evert(u);
Access(v),splay(v);
v->ch[]=u->fa=null;
v->maintain();
}
Node *find(Node *o) {
while(o->fa!=null) o=o->fa;
return o;
} }
using namespace LCT ; int n,m; int query(Node *u,Node* v)
{
evert(u);
Access(v),splay(v);
return v->maxe;
} int main()
{
// freopen("in.in","r",stdin);
// freopen("out.out","w",stdout);
n=read(),m=read();
int u,v,a,b;
FOR(i,,m) {
u=read(),v=read(),a=read(),b=read();
adde(u,v,a,b);
}
FOR(i,,m) E[i]=Node(i);
FOR(i,,n) T[i]=Node();
sort(e+,e+m+);
int ans=1e9;
FOR(i,,m) {
int u=e[i].u,v=e[i].v;
if(find(&T[u])==find(&T[v])) {
int maxe=query(&T[u],&T[v]);
if(e[i].b>=e[maxe].b) continue;
Cut(&E[maxe],&T[e[maxe].u]);
Cut(&E[maxe],&T[e[maxe].v]);
}
Link(&T[u],&E[i]);
Link(&T[v],&E[i]);
if(find(&T[])==find(&T[n])) {
int maxe=query(&T[],&T[n]);
if(e[maxe].b+e[i].a<ans) ans=e[maxe].b+e[i].a;
}
}
if(ans==1e9) puts("-1");
else printf("%d\n",ans);
return ;
}
3669 [Noi2014]魔法森林(LCT,最小生成树)的更多相关文章
- BZOJ 3669: [Noi2014]魔法森林(lct+最小生成树)
传送门 解题思路 \(lct\)维护最小生成树.我们首先按照\(a\)排序,然后每次加入一条边,在图中维护一棵最小生成树.用并查集判断一下\(1\)与\(n\)是否联通,如果联通的话就尝试更新答案. ...
- bzoj 3669: [Noi2014]魔法森林 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3669 题面: 3669: [Noi2014]魔法森林 Time Limit: 30 Sec ...
- BZOJ 3669: [Noi2014]魔法森林( LCT )
排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...
- bzoj 3669: [Noi2014] 魔法森林 LCT版
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
- BZOJ 3669: [Noi2014]魔法森林 [LCT Kruskal | SPFA]
题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2,3,…,n,边标号为 1,2,3,…, ...
- bzoj 3669: [Noi2014]魔法森林
bzoj 3669: [Noi2014]魔法森林 Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号 ...
- bzoj 3669: [Noi2014]魔法森林 动态树
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 363 Solved: 202[Submit][Status] ...
- bzoj 3669: [Noi2014]魔法森林 -- 动点spfa
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MB 动点spfa Description 为了得到书法大家的真传,小E同学下定决心 ...
- 【BZOJ 3669】 3669: [Noi2014]魔法森林 (动态spfa)
3669: [Noi2014]魔法森林 Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N ...
- [NOI2014]魔法森林 LCT
题面 [NOI2014]魔法森林 题解 一条路径的代价为路径上的\(max(a[i]) + max(b[i])\),因为一条边同时有$a[i], b[i]$2种权值,直接处理不好同时兼顾到,所以我们考 ...
随机推荐
- 深入探索 Java 热部署
在 Java 开发领域,热部署一直是一个难以解决的问题,目前的 Java 虚拟机只能实现方法体的修改热部署,对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作.对于某些大型的应用来 ...
- Android学习之-TextView的滑动效果
textView中如何设置滚动条 在xml中定义: <TextView android:layout_width="wrap_content" ...
- 纯后台生成highcharts图片有哪些方法?
比如说,领导抛给你一个需求,把一些数据做成图表,每天通过邮件发送,让领导能在邮件中就看到图片,你会有什么思路呢?本人使用的是phantomjs这个神器,它的内核是WebKit引擎,不提供图形界面,只能 ...
- MyEclipse +Servlet 乱码
用MyEclipse 新建了Web Project,然后建立了一个Servlet,在doGet方法中谢了简单的一句欢迎语句,本来以为平平常常的事情,但是却出错了,乱码问题,在网上找了一些帖子,说是设置 ...
- Java API —— Calendar类
1.Calendar类概述 Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR.MONTH.DAY_OF_MONTH.HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段 ...
- SQLserver游标原理和使用方法
在数据库开发过程中,当你检索的数据只是一条记录时,你所编写的事务语句代码往往使用SELECT INSERT 语句.但是我们常常会遇到这样情况,即从某一结果集中逐一地读取一条记录.那么如何解决这种问题呢 ...
- (六)Ireport制作一个规范的报表,处理数据格式
转载:http://frankco.iteye.com/blog/1686651 删除注释信息,Report Respector面板中按住Ctrl鼠标选中位于报表每个部分的组件,使用键盘的方向键可以左 ...
- 2014年百度之星程序设计大赛 - 资格赛 1004 Labyrinth(Dp)
题目链接 题目: Labyrinth Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- [原创]Android中LocationManager的简单使用,获取当前位置
Android中LocationManager的提供了一系列方法来地理位置相关的问题,包括查询上一个已知位置:注册/注销来自某个 LocationProvider的周期性的位置更新:以及注册/注销接近 ...
- 对于oracle监听器的配置
oracle 的 net configuration assist中配置完第一项的监听程序配置(对应文件listener.ora)之后,还要重新配置下第三项本地网络服务名配置(对应文件tnsname ...