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种权值,直接处理不好同时兼顾到,所以我们考 ...
随机推荐
- python3.0与2.x之间的区别
python3.0与2.x之间的区别: 1.性能 Py3.0运行pystone benchmark的速度比Py2.5慢30%.Guido认为Py3.0有极大的优化空间,在字符串和整形操作上可以取得很好 ...
- iOS开发--数组
1.sortedArrayUsingSelector (按Key值大小对NSDictionary排序) NSMutableArray *array = [NSMutableArray arrayWit ...
- 用Eclipse编写运行Java程序
1.选择一个空的文件夹,作为workspace工作空间,用来存放你以后用eclipse写的Java程序.(一个workspace可以放很多很多project项目) 2.新建java项目:File-&g ...
- java获取当前操作系统的信息
java获取当前操作系统的信息 JavaOS虚拟机UnixEXT 从网上收集的一些关于java获取操作系统信息的方法,现在总结一下: 1获取本机的IP地址: private static Strin ...
- RESTful WebService入门
RESTful WebService入门 RESTful WebService是比基于SOAP消息的WebService简单的多的一种轻量级Web服务,RESTful WebService是没有状 ...
- C++:虚函数的引入
5.4虚函数5.4.1 虚函数的引入 //例5.19 虚函数的引例 #include<iostream> using namespace std; class MyBase{ //声明基类 ...
- Android如何获取开机启动项列表
static final String BOOT_START_PERMISSION = "android.permission.RECEIVE_BOOT_COMPLETED"; p ...
- Bean不同配置方式比较
基于XML配置 基于注解配置 基于Java类配置 Bean定义 在XML文件中通过<bean>元素定义Bean,如:<bean class="com.bbt.UserD ...
- 【POJ】3523 The Morning after Halloween
1. 题目描述$m \times n$的迷宫(最大为$16 \times 16$)包含最多3个点,这些点可以同时向相邻方向移动或保持停止,使用小写字母表示起始位置,使用大写字母表示中止位置.求最少经过 ...
- Base64 Encoding / Decoding in Node.js
Posted on April 20th, 2012 under Node.js Tags: ASCII, Buffer, Encoding, node.js, UTF So how do you e ...