BZOJ3669(NOI2014):魔法森林 (LCT维护最小生成树)
为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士。魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M。
初始时小E同学在号节点1,隐士则住在号节点N。小E需要通过这一片魔法森林,才能够拜访到隐士。
魔法森林中居住了一些妖怪。每当有人经过一条边的时候,这条边上的妖怪就会对其发起攻击。幸运的是,在号节点住着两种守护精灵:A型守护精灵与B型守护精灵。
小E可以借助它们的力量,达到自己的目的。
只要小E带上足够多的守护精灵,妖怪们就不会发起攻击了。具体来说,无向图中的每一条边Ei包含两个权值Ai与Bi。若身上携带的A型守护精灵个数不少于Ai,且B型
守护精灵个数不少于Bi,这条边上的妖怪就不会对通过这条边的人发起攻击。当且仅当通过这片魔法森林的过程中没有任意一条边的妖怪向小E发起攻击,他才能成功找到隐士。
由于携带守护精灵是一件非常麻烦的事,小E想要知道,要能够成功拜访到隐士,最少需要携带守护精灵的总个数。守护精灵的总个数为A型守护精灵的个数与B型守护精
灵的个数之和。
Input
第1行包含两个整数N,M,表示无向图共有N个节点,M条边。 接下来M行,第行包含4个正整数Xi,Yi,Ai,Bi,描述第i条无向边。其中Xi与Yi为该边两个端点的标号,Ai
与Bi的含义如题所述。 注意数据中可能包含重边与自环。 Output
输出一行一个整数:如果小E可以成功拜访到隐士,输出小E最少需要携带的守护精灵的总个数;如果无论如何小E都无法拜访到隐士,输出“-”(不含引号)。 Sample Input
【输入样例1】 【输入样例2】 Sample Output
【输出样例1】 【样例说明1】
如果小E走路径1→→,需要携带19+=34个守护精灵;
如果小E走路径1→→,需要携带17+=34个守护精灵;
如果小E走路径1→→→,需要携带19+=36个守护精灵;
如果小E走路径1→→→,需要携带17+=32个守护精灵。
综上所述,小E最少需要携带32个守护精灵。 【输出样例2】
-
【样例说明2】
小E无法从1号节点到达3号节点,故输出-。
Hint
<=n<=,
<=m<=,
<=ai ,bi<=,
题意:给定一个无向图,每条边有两个权值ai和bi,从1走到N,设路径上a权的最大值为A,b权的最大值为B,求A+B的最小值。n<=5*1e4. m<=5*1e4。
思路:要生成最小生成树(至少满足1和N连通),我们选择的边如果按A递增,那么易得B递减。现在按a从小到大排序,得到对于每个a,找到对应的b下限,如果连通,则更新答案。
具体可以看这里:http://www.cnblogs.com/hua-dong/p/8665998.html
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
const int inf=;
struct edge{
int x,y,a,b; }e[maxn];
bool cmp (edge w,edge v){
return w.a<v.a;
}
void read(int &x){
char c=getchar(); x=;
for(;c>''||c<'';c=getchar());
for(;c<=''&&c>='';c=getchar()) x=(x<<)+(x<<)+c-'';
}
struct LCT
{
int Max[maxn],rev[maxn],ch[maxn][],fa[maxn],stc[maxn],top;
int isroot(int x){
return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;
}
int get(int x){
return ch[fa[x]][]==x;
}
void pushdown(int x)
{
if(!rev[x]||!x) return ;
swap(ch[x][],ch[x][]);
if(ch[x][]) rev[ch[x][]]^=;
if(ch[x][]) rev[ch[x][]]^=;
rev[x]=;
}
void pushup(int x)
{
Max[x]=x;
if(ch[x][]&&e[Max[ch[x][]]].b>e[Max[x]].b) Max[x]=Max[ch[x][]];
if(ch[x][]&&e[Max[ch[x][]]].b>e[Max[x]].b) Max[x]=Max[ch[x][]];
}
void rotate(int x)
{
int old=fa[x],fold=fa[old],opt=get(x);
if(!isroot(old)) ch[fold][get(old)]=x;
fa[x]=fold;
ch[old][opt]=ch[x][opt^]; fa[ch[old][opt]]=old;
ch[x][opt^]=old; fa[old]=x;
pushup(old); pushup(x);
}
void splay(int x)
{
int top=; stc[++top]=x;
for(int i=x;!isroot(i);i=fa[i]) stc[++top]=fa[i];
for(int i=top;i;i--) pushdown(stc[i]);
for(int f;!isroot(x);rotate(x)){
if(!isroot(f=fa[x]))
rotate(get(x)==get(f)?f:x);
}
}
void access(int x)
{
int rson=;
for(;x;rson=x,x=fa[x]){
splay(x);
ch[x][]=rson;
pushup(x);
}
}
int find(int x){ access(x); splay(x); while(ch[x][]) x=ch[x][]; return x;}
int query(int x,int y) { make_root(y); access(x); splay(x); return Max[x]; }
void make_root(int x) { access(x); splay(x); rev[x]^=; }
void link(int x,int y) { make_root(x); fa[x]=y; splay(x); }
void cut(int x,int y) { make_root(x); access(y); splay(y); fa[x]=ch[y][]=; }
}S;
int main()
{
int N,M,i,ans=inf;
read(N); read(M);
for(i=;i<=M;i++){
read(e[i].x); read(e[i].y);
read(e[i].a); read(e[i].b);
}
sort(e+,e+M+,cmp);
for(i=;i<=M;i++){
if(S.find(M+e[i].x)!=S.find(M+e[i].y)) {
S.link(i,M+e[i].x);
S.link(i,M+e[i].y);
}
else{
int tmp=S.query(M+e[i].x,M+e[i].y);
if(e[tmp].b>e[i].b) {
S.cut(tmp,M+e[tmp].x); S.cut(tmp,M+e[tmp].y);
S.link(i,M+e[i].x); S.link(i,M+e[i].y);
}
}
if(S.find(M+)==S.find(M+N)){
int tmp=S.query(M+,M+N);
if(e[tmp].b+e[i].a<ans) ans=e[tmp].b+e[i].a;
}
}
if(ans==inf) ans=-;
printf("%d\n",ans);
return ;
}
BZOJ3669(NOI2014):魔法森林 (LCT维护最小生成树)的更多相关文章
- [BZOJ3669] [NOI2004] 魔法森林 LCT维护最小生成树
题面 一开始看到这道题虽然知道是跟LCT维护最小生成树相关的但是没有可以的去想. 感觉可以先二分一下总的精灵数,但是感觉不太好做. 又感觉可以只二分一种精灵,用最小生成树算另一种精灵,但是和似乎不单调 ...
- P2387 [NOI2014]魔法森林 LCT维护最小生成树
\(\color{#0066ff}{ 题目描述 }\) 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 ...
- bzoj3669: [Noi2014]魔法森林 lct版
先上题目 bzoj3669: [Noi2014]魔法森林 这道题首先每一条边都有一个a,b 我们按a从小到大排序 每次将一条路劲入队 当然这道题权在边上 所以我们将边化为点去连接他的两个端点 当然某两 ...
- 【BZOJ 3669】 [Noi2014]魔法森林 LCT维护动态最小生成树
这道题看题意是在求一个二维最小瓶颈路,唯一可行方案就是枚举一维在这一维满足的条件下使另一维最小,那么我们就把第一维排序利用A小的边在A大的情况下仍成立来动态加边维护最小生成树. #include &l ...
- [Luogu P2387] [NOI2014]魔法森林 (LCT维护边权)
题面 传送门:https://www.luogu.org/problemnew/show/P2387 Solution 这题的思想挺好的. 对于这种最大值最小类的问题,很自然的可以想到二分答案.很不幸 ...
- Vijos1865 NOI2014 魔法森林 LCT维护生成树
基本思路: 首先按照weightA升序排序,然后依次在图中加边,并维护起点到终点路径上weightB的最大值 如果加边过程中生成了环,则删除环中weightB最大的边 由于是无向图,点之间没有拓扑序, ...
- 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\)维护最小生成树.我们首先按照\(a\)排序,然后每次加入一条边,在图中维护一棵最小生成树.用并查集判断一下\(1\)与\(n\)是否联通,如果联通的话就尝试更新答案. ...
- bzoj 3669: [Noi2014]魔法森林 (LCT)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3669 题面: 3669: [Noi2014]魔法森林 Time Limit: 30 Sec ...
随机推荐
- 可以学习相关框架【转:https://testerhome.com/topics/6283】
https://testerhome.com/topics/6283 单元测试方面(Java): Junit:本来想用我熟悉的testng,但是开发的同学说测试springmvc只能用Junit.所以 ...
- for-else和wihle-else组合用法
当for和else组合一起使用的时候,for循环正常执行完毕,会执行else语句,否则,不会执行else语句 for i in range(10): if i == 2: break else: pr ...
- 【Java源码】集合类-LinkedList
一.类继承关系 LinkedList和ArrayList都实现了List接口.所以有List的特性,同时LinkedList也实现了Deque,所以它也具有双端队列和栈的特性. public clas ...
- 集群架构和CentOS7安装RabbitMQ集群(单机版)
1. 集群架构 1.1 四种内部元数据 队列元数据.交换器元数据.绑定元数据.vhost元数据. 单一节点中:会将数据存储到内存,同时将持久化元数据保存到硬盘. 集群中: 存储到磁盘上.内存中. 集群 ...
- poj——3177Redundant Paths
poj——3177Redundant Paths 洛谷—— P2860 [USACO06JAN]冗余路径Redundant Paths Time Limit: 1000MS Memory ...
- Google的Guava类库简介(转)
说明:信息虽然有点旧,至少可以先了解个大概. Guava是一个Google的基于Java的类库集合的扩展项目,包括collections, caching, primitives support, c ...
- struts2 动态工作流
话不多说,直接贴代码: public class TestAction { private String nextPage;//保存下一步内容的属性 public String destroy(){ ...
- 【APUE】进程基础
进程标识符:非负整数 ID为0的进程通常是是调度进程,常被称为交换进程.该进程是内核的一部分,它并不执行任何磁盘上的程序,因此也被称为系统进程 ID为1的进程是init进程,在自举过程结束时由内核调用 ...
- 【APUE】文件I/O
Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file descri ...
- Capture and report JavaScript errors with window.onerror
原文:https://blog.sentry.io/2016/01/04/client-javascript-reporting-window-onerror.html onerror is a sp ...