【BZOJ3669】【NOI2014】魔法森林 LCT
题目描述
给你一个\(n\)个点\(m\)条边的图,每条边有两个边权\(a,b\)。请你找出从\(1\)到\(n\)一条路径,使得这条路径上边权\(a\)的最大值\(+\)边权\(b\)的最大值最小。
\(n\leq 50000,m\leq 100000\)
题解
我们可以考虑求出当边权\(a\leq\)某个数时边权\(b\)的最大值。
先把边按边权\(a\)从小到大排序,依次加入,用LCT维护当前边权\(b\)的最小生成树。如果这两个点已经联通,就判断这两个点路径上边的边权\(b\)的最大值,如果大于当前这条边的边权\(b\),就把这条边删掉。否则就不加入这条边。
每加完一条边我们就可以认为从\(1\)到\(n\)的边权\(a\)的最大值为当前这条边的边权\(a\)(否则就会在之前更新到),然后查询\(1\)到\(n\)的边权\(b\)的最大值,更新答案。
时间复杂度:\(O(m\log n)\)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
namespace lct
{
int a[200010][2];
int f[200010];
pii v[200010];
pii s[200010];
int r[200010];
int root(int x)
{
return !f[x]||(a[f[x]][0]!=x&&a[f[x]][1]!=x);
}
void reverse(int x)
{
swap(a[x][0],a[x][1]);
r[x]^=1;
}
void push(int x)
{
if(r[x])
{
if(a[x][0])
reverse(a[x][0]);
if(a[x][1])
reverse(a[x][1]);
r[x]=0;
}
}
void mt(int x)
{
s[x]=max(v[x],max(s[a[x][0]],s[a[x][1]]));
}
void rotate(int x)
{
if(root(x))
return;
int p=f[x];
int q=f[p];
int ps=(x==a[p][1]);
int qs=(p==a[q][1]);
int ch=a[x][ps^1];
if(!root(p))
a[q][qs]=x;
a[x][ps^1]=p;
a[p][ps]=ch;
if(ch)
f[ch]=p;
f[p]=x;
f[x]=q;
mt(p);
mt(x);
}
void clear(int x)
{
if(!root(x))
clear(f[x]);
push(x);
}
void splay(int x)
{
clear(x);
int p,q;
while(!root(x))
{
p=f[x];
if(!root(p))
{
q=f[p];
if((p==a[q][1])==(x==a[p][1]))
rotate(p);
else
rotate(x);
}
rotate(x);
}
}
void access(int x)
{
int y=x,t=0;
while(x)
{
splay(x);
a[x][1]=t;
mt(x);
t=x;
x=f[x];
}
splay(y);
}
void change(int x)
{
access(x);
reverse(x);
}
int findroot(int x)
{
access(x);
while(a[x][0])
x=a[x][0];
splay(x);
return x;
}
pii query(int x,int y)
{
change(x);
access(y);
return s[y];
}
void link(int x,int y)
{
change(x);
f[x]=y;
}
void cut(int x,int y)
{
change(x);
access(y);
f[a[y][0]]=0;
a[y][0]=0;
mt(y);
}
}
struct edge
{
int x,y;
int a,b;
};
edge a[100010];
int cmp(edge a,edge b)
{
return a.a<b.a;
}
int main()
{
// freopen("bzoj3669.in","r",stdin);
// freopen("bzoj3669.out","w",stdout);
int n,m;
scanf("%d%d",&n,&m);
int i;
for(i=1;i<=m;i++)
scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].a,&a[i].b);
sort(a+1,a+m+1,cmp);
int ans=0x7fffffff;
for(i=1;i<=m;i++)
{
if(a[i].x==a[i].y)
continue;
if(lct::findroot(a[i].x)==lct::findroot(a[i].y))
{
pii s=lct::query(a[i].x,a[i].y);
if(a[i].b>=a[s.second].b)
continue;
lct::cut(s.second+n,a[s.second].x);
lct::cut(s.second+n,a[s.second].y);
}
lct::v[i+n]=pii(a[i].b,i);
lct::link(a[i].x,i+n);
lct::link(a[i].y,i+n);
if(lct::findroot(1)==lct::findroot(n))
ans=min(ans,a[i].a+lct::query(1,n).first);
}
if(ans==0x7fffffff)
ans=-1;
printf("%d\n",ans);
return 0;
}
【BZOJ3669】【NOI2014】魔法森林 LCT的更多相关文章
- bzoj3669: [Noi2014]魔法森林 lct版
先上题目 bzoj3669: [Noi2014]魔法森林 这道题首先每一条边都有一个a,b 我们按a从小到大排序 每次将一条路劲入队 当然这道题权在边上 所以我们将边化为点去连接他的两个端点 当然某两 ...
- bzoj3669: [Noi2014]魔法森林 lct
记得去年模拟赛的时候好像YY出二分答案枚举a,b的暴力,过了55欸 然后看正解,为了将两维变成一维,将a排序,模拟Kruskal的加边过程,同时维护1到n的最大值,加入一条边e(u,v,a,b)时有以 ...
- [bzoj3669][Noi2014]魔法森林——lct
Brief description 给定一个无向图,求从1到n的一条路径使得这条路径上最大的a和b最小. Algorithm Design 以下内容选自某HN神犇的blog 双瓶颈的最小生成树的感觉, ...
- BZOJ 3669: [Noi2014]魔法森林( LCT )
排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...
- bzoj 3669: [Noi2014]魔法森林 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3669 题面: 3669: [Noi2014]魔法森林 Time Limit: 30 Sec ...
- [NOI2014]魔法森林 LCT
题面 [NOI2014]魔法森林 题解 一条路径的代价为路径上的\(max(a[i]) + max(b[i])\),因为一条边同时有$a[i], b[i]$2种权值,直接处理不好同时兼顾到,所以我们考 ...
- loj2245 [NOI2014]魔法森林 LCT
[NOI2014]魔法森林 链接 loj 思路 a排序,b做动态最小生成树. 把边拆成点就可以了. uoj98.也许lct复杂度写假了..越卡常,越慢 代码 #include <bits/std ...
- 【BZOJ3669】[Noi2014]魔法森林 LCT
终于不是裸的LCT了...然而一开始一眼看上去这是kruskal..不对,题目要求1->n的路径上的每个点的两个最大权值和最小,这样便可以用LCT来维护一个最小生成路(瞎编的...),先以a为关 ...
- BZOJ3669[Noi2014]魔法森林——kruskal+LCT
题目描述 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节点1,隐士则住 ...
- BZOJ3669: [Noi2014]魔法森林(瓶颈生成树 LCT)
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 3558 Solved: 2283[Submit][Status][Discuss] Descript ...
随机推荐
- Leetcode 中Linked List Cycle 一类问题
141. Linked List Cycle Given a linked list, determine if it has a cycle in it. Follow up:Can you sol ...
- H5 32-百度首页
32-百度首页 新 闻 网 页 贴 吧 知 道 音 乐 图 片 视 频 地 图 百科 文库 hao123 | 更多>> 百度地图带你吃喝玩乐,全心全意为人民服务 把百度设为主页 安装百度卫 ...
- Really Big Numbers CodeForces - 817C (数学规律+二分)
C. Really Big Numbers time limit per test 1 second memory limit per test 256 megabytes input standar ...
- Python的math模块
ceil(x) 返回整数 >>> math.ceil(-1.273) -1 >>> math.ceil(1.33) 2 copysign(x,y) 把y的符号给x, ...
- K8S、云计算、大数据、编程语言
云计算.大数据.编程语言学习指南下载,100+技术课程免费学!这份诚意满满的新年技术大礼包,你Get了吗?-云栖社区-阿里云https://yq.aliyun.com/articles/691028 ...
- How To: Capture Android & iOS Traffic with Fiddler
How To: Capture iOS Traffic with Fiddlerhttps://www.telerik.com/blogs/how-to-capture-ios-traffic-wit ...
- HDU 2459 Maximum repetition substring
题目:Maximum repetition substring 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2459 题意:给你一个字符串,求连续重复出现 ...
- input type=date时,时间数据回填,报错The specified value "2019-0404-18" does not conform to the required format, "yyyy-MM-dd".
<input autocomplete id="start-time" name="start_time" type="date" c ...
- cookie路径概念理解
.创建一个cookie并设置 cookie的有效路径: $.cookie('the_cookie', 'the_value', { expires: 7, path: '/' }); 注:在默认情况下 ...
- windos安装maven
1.下载好maven压缩包,并解压到相应位置,本次安装在D: 2.配置环境变量 MAVEN_HOME=D:\apache-maven-3.0.5 path=%MAVEN_HOME% 3.生成maven ...