【题目链接】

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,最小生成树)的更多相关文章

  1. BZOJ 3669: [Noi2014]魔法森林(lct+最小生成树)

    传送门 解题思路 \(lct\)维护最小生成树.我们首先按照\(a\)排序,然后每次加入一条边,在图中维护一棵最小生成树.用并查集判断一下\(1\)与\(n\)是否联通,如果联通的话就尝试更新答案. ...

  2. bzoj 3669: [Noi2014]魔法森林 (LCT)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3669 题面: 3669: [Noi2014]魔法森林 Time Limit: 30 Sec  ...

  3. BZOJ 3669: [Noi2014]魔法森林( LCT )

    排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...

  4. bzoj 3669: [Noi2014] 魔法森林 LCT版

    Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...

  5. BZOJ 3669: [Noi2014]魔法森林 [LCT Kruskal | SPFA]

    题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2,3,…,n,边标号为 1,2,3,…, ...

  6. bzoj 3669: [Noi2014]魔法森林

    bzoj 3669: [Noi2014]魔法森林 Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号 ...

  7. bzoj 3669: [Noi2014]魔法森林 动态树

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 363  Solved: 202[Submit][Status] ...

  8. bzoj 3669: [Noi2014]魔法森林 -- 动点spfa

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MB 动点spfa Description 为了得到书法大家的真传,小E同学下定决心 ...

  9. 【BZOJ 3669】 3669: [Noi2014]魔法森林 (动态spfa)

    3669: [Noi2014]魔法森林 Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N ...

  10. [NOI2014]魔法森林 LCT

    题面 [NOI2014]魔法森林 题解 一条路径的代价为路径上的\(max(a[i]) + max(b[i])\),因为一条边同时有$a[i], b[i]$2种权值,直接处理不好同时兼顾到,所以我们考 ...

随机推荐

  1. Excel操作--使用NPOI导入导出Excel为DataTable

    1.ExcelHelper封装 namespace NPOI操作Excel { public class ExcelHelper { /// <summary> /// DataTable ...

  2. Intellij IDEA调试功能

    public class Demo { public static void f1() { System.out.println("one"); System.out.printl ...

  3. Android 清除canvas 笔迹代码

    canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); canvas.drawLine(pointX, , event.getX(), ...

  4. UPC 2224 / “浪潮杯”山东省第四届ACM大学生程序设计竞赛 1008 Boring Counting 主席树

    Problem H:Boring Counting Time Limit : 6000/3000ms (Java/Other)   Memory Limit : 65535/32768K (Java/ ...

  5. 《数据通信与网络》笔记--TCP中的拥塞控制

    1.拥塞窗口 发送方窗口的大小不仅取决于接收方,而.而且还取决于网络拥塞的情况. 发送方有2种信息:接收方通告的窗口大小和拥塞窗口的大小,实际的窗口大小事这两者中的最小者. 实际窗口大小 = min( ...

  6. Xmanager Enterprise Linking VM Redhat Linux AS4.7 X64–Server Configuration

      [root@localhost ~]# vi /etc/inittab ## inittab       This file describes how the INIT process shou ...

  7. Android仿iPhone晃动撤销输入功能(微信摇一摇功能)

    重力传感器微信摇一摇SensorMannager自定义alertdialogSensorEventListener 很多程序中我们可能会输入长文本内容,比如短信,写便笺等,如果想一次性撤销所有的键入内 ...

  8. HDU 1711 (裸KMP) Number Sequence

    题意: 用第二个数列去匹配第一个数列,输出第一次匹配到的位置,如果没有则输出-1. 分析: 这明显是一道裸的KMP. 我是在这篇博客上学的KMP算法的,讲得比较透彻. http://blog.csdn ...

  9. bzoj1601: [Usaco2008 Oct]灌水

    经典延伸最小生成树问题... #include<cstdio> #include<cstring> #include<cctype> #include<alg ...

  10. [POJ 3498] March of the Penguins

    March of the Penguins Time Limit: 8000MS   Memory Limit: 65536K Total Submissions: 4378   Accepted:  ...