大概题意:给一个无向图,有a,b两种边权,找一条从1到n的路径,使得max(a[i])+max(b[i])最小a[i],b[i]表示该路径上的边的对应权。

如果用类似最短路的DP来做,显然每个点的状态就必须是一个集合,保存的是一个下凸的点集,表示到达这个点的最小的a,b,这样肯定会挂,但该该种做法已经无法再优化或减少状态了。

考虑枚举其中一个权值b0,然后只考虑所有b权值小于等于b0的边,然后变成简单的问题,因为这个b0不满足二分三分之类的性质,所以肯定不能每次重建图,跑DP,最终的做法是从小到大枚举一维权值,然后不断地加边进入边,维护一个当前图的最小生成树(用LCT实现)。

收获:

  1、如果一个东西不满足二分三分,可以尝试从动态的角度,暴力枚举,用数据结构保证复杂度。

 /**************************************************************
Problem: 3669
User: idy002
Language: C++
Result: Accepted
Time:6680 ms
Memory:12536 kb
****************************************************************/ #include <cstdio>
#include <algorithm>
#define oo 0x3f3f3f3f
#define N 200010
using namespace std; struct Edge {
int u, v, a, b;
Edge(){}
Edge( int u, int v, int a, int b ):u(u),v(v),a(a),b(b){}
bool operator<( const Edge &e ) const { return b<e.b; }
};
struct LCT {
int son[N][], pre[N], pnt[N], rtg[N], ntot;
int trash[N], stot;
int val[N], vmx[N], vnd[N], uu[N], vv[N]; inline int newnode( int p, int va, int u, int v ) {
int nd = stot ? trash[stot--] : ++ntot;
pre[nd] = p;
son[nd][] = son[nd][] = pnt[nd] = ;
rtg[nd] = ;
val[nd] = vmx[nd] = va;
vnd[nd] = nd;
uu[nd] = u;
vv[nd] = v;
return nd;
}
void update( int nd ) {
vmx[nd] = val[nd];
vmx[nd] = max( vmx[nd], vmx[son[nd][]] );
vmx[nd] = max( vmx[nd], vmx[son[nd][]] );
if( vmx[nd]==val[nd] )
vnd[nd] = nd;
else if( vmx[nd]==vmx[son[nd][]] )
vnd[nd] = vnd[son[nd][]];
else
vnd[nd] = vnd[son[nd][]];
}
void rotate( int nd, int d ) {
int p = pre[nd];
int s = son[nd][!d];
int ss = son[s][d]; son[nd][!d] = ss;
son[s][d] = nd;
if( p ) son[p][ nd==son[p][] ] = s;
else pnt[s]=pnt[nd], pnt[nd]=; pre[nd] = s;
pre[s] = p;
if( ss ) pre[ss] = nd; update(nd);
update(s);
}
void bigp( int nd ) {
if( pre[nd] ) bigp(pre[nd]);
if( rtg[nd] ) {
rtg[son[nd][]] ^= ;
rtg[son[nd][]] ^= ;
swap( son[nd][], son[nd][] );
rtg[nd] = ;
}
}
void splay( int nd, int top= ) {
bigp(nd);
while( pre[nd]!=top ) {
int p=pre[nd];
int nl=nd==son[p][];
if( pre[p]==top ) {
rotate( p, nl );
} else {
int pp=pre[p];
int pl=p==son[pp][];
if( nl==pl ) {
rotate( pp, pl );
rotate( p, nl );
} else {
rotate( p, nl );
rotate( pp, pl );
}
}
}
}
void access( int nd ) {
int u = nd;
int v = ;
while( u ) {
splay( u );
int s=son[u][];
if( s ) {
pre[s] = ;
pnt[s] = u;
}
son[u][] = ;
if( v ) {
pre[v] = u;
pnt[v] = ;
}
son[u][] = v;
update(u);
v = u;
u = pnt[u];
}
splay( nd );
}
void makeroot( int u ) {
access(u);
rtg[u] ^= ;
}
void init( int n ) {
ntot = n;
val[] = -;
}
int findroot( int u ) {
while( pre[u] ) u=pre[u];
while( pnt[u] ) {
u=pnt[u];
while( pre[u] ) u=pre[u];
}
return u;
}
bool sameroot( int u, int v ) {
return findroot(u)==findroot(v);
}
int query( int s, int t ) {
makeroot(s);
access(t);
return vmx[t];
}
void addedge( int u, int v, int w ) {
// fprintf( stderr, "addedge( %d %d %d )\n", u, v, w );
if( sameroot(u,v) ) {
if( query(u,v)<=w ) return;
makeroot(u);
access(v);
int nd = vnd[v];
int l = uu[nd];
int r = vv[nd];
makeroot(l);
access(r);
bigp(l);
int e = son[r][];
while( son[e][] ) e=son[e][];
splay(e);
pre[l] = pre[r] = ;
trash[++stot] = e;
}
makeroot(u);
makeroot(v);
int nd = newnode(,w,u,v);
pnt[u] = nd;
pnt[v] = nd;
}
void print() {
fprintf( stderr, "\n" );
for( int i=; i<=ntot; i++ ) {
int nd = i;
for( int j=; j<=stot; j++ )
if( i==trash[j] )
goto Next;
fprintf( stderr, "%d pnt=%d pre=%d ls=%d rs=%d rtg=%d val=%d vmx=%d vnd=%d uu=%d vv=%d\n",
nd, pnt[nd], pre[nd], son[nd][], son[nd][], rtg[nd], val[nd], vmx[nd], vnd[nd], uu[nd], vv[nd] );
Next:;
}
}
}T; int n, m;
Edge edge[N]; int main() {
scanf( "%d%d", &n, &m );
for( int i=,u,v,a,b; i<=m; i++ ) {
scanf( "%d%d%d%d", &u, &v, &a, &b );
edge[i] = Edge(u,v,a,b);
}
sort( edge+, edge++m );
T.init(n);
int ans = oo;
for( int i=,j; i<=m; i=j ) {
for( j=i; j<=m; j++ ) {
if( edge[j].b==edge[i].b )
T.addedge(edge[j].u,edge[j].v,edge[j].a);
else break;
}
if( !T.sameroot(,n) ) continue;
ans = min( ans, edge[i].b+T.query(,n) );
}
printf( "%d\n", ans==oo ? - : ans );
}

bzoj 3669 lct维护最小生成树的更多相关文章

  1. BZOJ4668 冷战(LCT维护最小生成树)

    BZOJ4668 冷战(LCT维护最小生成树) 题面 自己找去 HINT 这道题就是动态加边,然后查询u,v两点最早什么时候联通,强制在线.思考一下,最早什么时候联通不就等同于维护最小生成树吗(把这条 ...

  2. BZOJ2594 [Wc2006]水管局长数据加强版 【LCT维护最小生成树】

    题目 SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的 ...

  3. [BZOJ3669] [NOI2004] 魔法森林 LCT维护最小生成树

    题面 一开始看到这道题虽然知道是跟LCT维护最小生成树相关的但是没有可以的去想. 感觉可以先二分一下总的精灵数,但是感觉不太好做. 又感觉可以只二分一种精灵,用最小生成树算另一种精灵,但是和似乎不单调 ...

  4. P4172 [WC2006]水管局长 LCT维护最小生成树

    \(\color{#0066ff}{ 题目描述 }\) SC 省 MY 市有着庞大的地下水管网络,嘟嘟是 MY 市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的 ...

  5. 洛谷2387 NOI2014魔法森林(LCT维护最小生成树)

    本题是运用LCT来维护一个最小生成树. 是一个经典的套路 题目中求的是一个\(max(a_i)+max(b_i)\)尽可能小的路径. 那么这种的一个套路就是,先按照一维来排序,然后用LCT维护另一维 ...

  6. P2387 [NOI2014]魔法森林 LCT维护最小生成树

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

  7. BZOJ 2594: [Wc2006]水管局长数据加强版 (LCT维护最小生成树)

    离线做,把删边转化为加边,那么如果加边的两个点不连通,直接连就行了.如果联通就找他们之间的瓶颈边,判断一下当前边是否更优,如果更优就cut掉瓶颈边,加上当前边. 那怎么维护瓶颈边呢?把边也看做点,向两 ...

  8. 洛谷P2387 [NOI2014]魔法森林(lct维护最小生成树)

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

  9. BZOJ3669(NOI2014):魔法森林 (LCT维护最小生成树)

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

随机推荐

  1. 使用 script 命令记录用户操作行为

    Script 命令可以帮助管理员记录用户的操作行为,包括用户查看文件中的哪些具体内容,写入了哪些文件,写了些什么都能看到,比较详细的记录了用户的操作行为. 本文对此进行简要说明. 1.添加日志记录 e ...

  2. 微信web开发者工具无法打开的解决方法

    参考网址:https://blog.csdn.net/gz506840597/article/details/77915488 我试了上面兄弟说的方法还是无效 下面说说我的方法: 我打开文件所在位置, ...

  3. JVM常用启动参数+常用内存调试工具

    一.JVM常用启动参数 -Xms:设置堆的最小值. -Xmx:设置堆的最大值. -Xmn:设置新生代的大小. -Xss:设置每个线程的栈大小. -XX:NewSize:设置新生代的初始值. -XX:M ...

  4. sqlserver中查询存储过程中的字符串

    select name from sysobjects o, syscomments s where o.id = s.id and text like '%querytext%' and o.xty ...

  5. Ubuntu下软件安装方式、PATH配置、查找安装位置

    Ubuntu 18.04, 安装方式 目前孤知道的Ubuntu下安装软件方式有3种(命令): 1.make 2.apt/apt-get 3.dpkg 方式1基于软件源码安装,需要经历配置(可选).编译 ...

  6. 基于gRpc的远程服务框架

    作为一个新搭建的软件团队,底层技术尤为重要.为了以后更好的面向不同的项目需求,满足不断变化的需求,决定着手搭建一套RPC系统.为了更好的兼容以后部门其他语言的使用,选择了开源框架gRpc. gRpc ...

  7. 实现nlp文本生成中的beam search解码器

    自然语言处理任务,比如caption generation(图片描述文本生成).机器翻译中,都需要进行词或者字符序列的生成.常见于seq2seq模型或者RNNLM模型中. 这篇博文主要介绍文本生成解码 ...

  8. ASP.NET MVC5+ 路由特性

    概述 ASP.NET MVC 5支持一种新的路由协议,称为路由特性. MVC5也支持以前定义路由的方式,你可以在一个项目中混合使用这两种方式来定义路由. 案例 1.使用Visual Studio 20 ...

  9. 易普优APS与国外知名高级计划排程系统对比

    众所周知软件执行效率受制于硬件性能,市面上的APS产品多为单机版本,企业要应用好APS,保证紧急插单.计划下发全程无忧,用户电脑硬件性能是不容忽视的一大瓶颈.APS的直接用户是车间管理人员.计划员,而 ...

  10. C#一步一步学网络辅助开发(1)--常用抓包工具的使用

    这次写的是一个系列,是让大家了解如何进行网络的辅助开发.要进行网络辅助开发抓包工具是必不可少的,下面就让大家熟悉一下常用的一些抓包工具, 1,Fiddler 这个工具是我目前用的最多的一款抓包工具,不 ...