[BZOJ 2594] [Wc2006]水管局长数据加强版 【LCT】

题目链接:BZOJ - 2594

 

题目分析

这道题如果没有删边的操作,那么就是 NOIP2013 货车运输,求两点之间的一条路径,使得边权最大的边的边权尽量小。

那么,这条路径就是最小生成树上这两点之间的路径。

然而现在有了删边操作,我们就需要一直维护当前的最小生成树。

删边然后维护 MST 还是不会做的,但是加边维护 MST 就可以用 LCT 来做了。于是,我们将询问和操作都记录下来,离线倒着做,就变成加边了。

加边维护 MST 的做法:

对于新加的一条边 (u, v, w) ,我们先求出现有 MST 中 u 到 v 的路径中,边权最大的边,如果这条边权最大的边的边权大于 w ,我们就将这条边删掉,将新加的边连上,加入 MST 。

否则,我们就忽略新加的这条边。

怎样处理边呢?我们把边看做和两个端点分别相连的一个点,即如果有一条边 (u, v) ,标号为 i ,那么我们就是连边 u -> i -> v ,就可以用 LCT 做了。

技巧:Splay 中一个节点就维护它的子树中边权最大的边的标号就可以了。

写代码时出现的错误:新加入一条边 (u, v, w) 时,发现现有 MST u 到 v 的路径上边权最大的边的边权 > w,需要删掉这条边,然后这条边是 T[t] ,t 是提取出的 u 到 v 的路径的 Splay 的根,

于是我 Cut(u, T[t]); Cut(v, T[t]); 然后就...就 0 分了。因为第一个 Cut 做完之后 T[t] 就改变了啊!!需要先记录下来然后再做两次 Cut !

 

代码

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>using namespace std;inline void Read(int &Num)
{char c = getchar();while (c < '0' || c > '9') c = getchar();Num = c - '0'; c = getchar();while (c >= '0' && c <= '9'){Num = Num * 10 + c - '0';c = getchar();}
}const int MaxN = 100000 + 5, MaxM = 1000000 + 5, MaxT = 1100000 + 5, MaxQ = 100000 + 5;int n, m, q, Top, Tot;
int Father[MaxT], Son[MaxT][2], V[MaxT], T[MaxT], f[MaxN], Size[MaxN], Ans[MaxQ];bool isRoot[MaxT], Rev[MaxT];struct ES
{int u, v, w, Idx;bool Del;
} E[MaxM];struct QR
{int f, x, y, Pos;
} Q[MaxQ];inline bool CmpW(ES e1, ES e2)
{return e1.w < e2.w;
}inline bool CmpIdx(ES e1, ES e2)
{return e1.Idx < e2.Idx;
}inline bool CmpUV(ES e1, ES e2)
{return (e1.u < e2.u) || (e1.u == e2.u && e1.v < e2.v);
}int FindIdx(int x, int y)
{if (x > y) swap(x, y);int l, r, mid;l = 1; r = m;while (l <= r){mid = (l + r) >> 1;if (E[mid].u == x && E[mid].v == y) break;if ((E[mid].u < x) || (E[mid].u == x && E[mid].v < y)) l = mid + 1;else r = mid - 1;}return mid;
}inline int Find(int x)
{int i, j, k;j = x;while (j != f[j]) j = f[j];i = x;while (i != j){k = i;i = f[i];f[k] = j;}return j;
}inline void UN(int x, int y)
{if (Size[x] == Size[y]) ++Size[x];if (Size[x] > Size[y]) f[y] = x;else f[x] = y;
}/********************* LCT Begin *********************/inline int gmax(int a, int b) {return V[a] > V[b] ? a : b;}inline void Update(int x)
{T[x] = gmax(x, gmax(T[Son[x][0]], T[Son[x][1]]));
}inline void Reverse(int x)
{Rev[x] = !Rev[x];swap(Son[x][0], Son[x][1]);
}inline void PushDown(int x)
{if (!Rev[x]) return;Rev[x] = false;if (Son[x][0]) Reverse(Son[x][0]);if (Son[x][1]) Reverse(Son[x][1]);
}inline int GetDir(int x)
{if (x == Son[Father[x]][0]) return 0;else return 1;
}void Rotate(int x)
{int y = Father[x], f;PushDown(y); PushDown(x);if (x == Son[y][0]) f = 1;else f = 0;if (isRoot[y]){isRoot[y] = false;isRoot[x] = true;} else{if (y == Son[Father[y]][0]) Son[Father[y]][0] = x;else Son[Father[y]][1] = x;}Father[x] = Father[y];Son[y][f ^ 1] = Son[x][f];if (Son[x][f]) Father[Son[x][f]] = y;Son[x][f] = y;Father[y] = x;Update(y); Update(x);
}void Splay(int x)
{int y;while (!isRoot[x]){y = Father[x];if (isRoot[y]){Rotate(x);break;}if (GetDir(y) == GetDir(x)) Rotate(y);else Rotate(x);Rotate(x);}
}int Access(int x)
{int y = 0;while (x != 0){Splay(x);PushDown(x);if (Son[x][1]) isRoot[Son[x][1]] = true;Son[x][1] = y;if (y) isRoot[y] = false;Update(x);y = x;x = Father[x];}return y;
}inline void Make_Root(int x)
{int t = Access(x);Reverse(t);
}void Link(int x, int y)
{Make_Root(x);Splay(x);Father[x] = y;
}void Cut(int x, int y)
{Make_Root(x);Access(y);Splay(y);PushDown(y);isRoot[Son[y][0]] = true;Father[Son[y][0]] = 0;Son[y][0] = 0;Update(y);
}/********************* LCT End *********************/int main()
{scanf("%d%d%d", &n, &m, &q);for (int i = 1; i <= m; ++i){Read(E[i].u); Read(E[i].v); Read(E[i].w);if (E[i].u > E[i].v) swap(E[i].u, E[i].v);E[i].Del = false;}sort(E + 1, E + m + 1, CmpW); // by ES.wfor (int i = 1; i <= m; ++i){E[i].Idx = i;V[n + i] = E[i].w;}for (int i = 1; i <= n + m; ++i){isRoot[i] = true;Father[i] = 0;T[i] = i;}sort(E + 1, E + m + 1, CmpUV); // by ES.u && ES.vint t;for (int i = 1; i <= q; ++i){Read(Q[i].f); Read(Q[i].x); Read(Q[i].y);if (Q[i].f == 2){t = FindIdx(Q[i].x, Q[i].y);E[t].Del = true;Q[i].Pos = E[t].Idx;}else ++Top;}Tot = Top;for (int i = 1; i <= n; ++i){f[i] = i;Size[i] = 1;}sort(E + 1, E + m + 1, CmpIdx); // by ES.Idxint Cnt = 0, fx, fy;for (int i = 1; i <= m; ++i){if (E[i].Del) continue;fx = Find(E[i].u); fy = Find(E[i].v);if (fx == fy) continue;UN(fx, fy);Link(E[i].u, n + i); Link(E[i].v, n + i);if (++Cnt == n - 1) break;}int CutE;for (int i = q; i >= 1; --i){Make_Root(Q[i].x);t = Access(Q[i].y);if (Q[i].f == 1) Ans[Top--] = V[T[t]];else{if (E[Q[i].Pos].w >= V[T[t]]) continue;CutE = T[t];Cut(CutE, E[CutE - n].u); Cut(CutE, E[CutE - n].v);Link(Q[i].x, n + Q[i].Pos); Link(Q[i].y, n + Q[i].Pos);}}for (int i = 1; i <= Tot; ++i) printf("%d\n", Ans[i]);return 0;
}

  

转载于:https://www.cnblogs.com/JoeFan/p/4450750.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/574640.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vs升级c++项目遇到的一些问题

1、error C1189: #error : This file requires _WIN32_WINNT to be #defined at least to 0x0403. Value 0x0501 or higher is recommended. 在工程的stdafx.h中&#xff0c;改为如下配置&#xff1a; #ifndef WINVER #define WINVER 0x0501 #endif #ifndef _WIN32_WINNT #def…

python模糊匹配忽略大小写_在python中忽略大小写的简单方法?

如果搜索多个单词&#xff0c;则创建一个集合是有意义的&#xff1a;print(set(brown_sents).intersection(zip(repeat(most_ambiguous_word),word_class_dict[most_ambiguous_word])))输出{(word2, wordclass2), (word2, wordclass3)}要理解它的作用&#xff0c;请将脚本保存到…

IAR7.51提示秘钥无效IAR 以及 CCDebug驱动(包含win7 64bit)

今天IAR不识别我的仿真器&#xff0c;然后我感觉驱动有问题&#xff0c;就把之前的驱动卸载了&#xff0c;但是按照以前的方法按章驱动(选择路径到IAR的某个目录)&#xff0c;提示找不到驱动。。。 也不想重新装个IAR了&#xff0c;于是到CSDN上下载了这个驱动程序&#xff0c;…

cannot be resolved or is not a field

我通常的解决办法&#xff1a;1.看看是不是manifest.xml文件有错误&#xff0c;如果有的话&#xff0c;R.java是不会生成的2.一般来说R.layout.aaa.xml&#xff0c;这里的R是自己的包的R.java&#xff0c;不是android系统的R.java&#xff0c;所以如果引入包的时候有import and…

java解析时已到达文件结尾_IO流读取到文件末尾继续读取

import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;//正常情况//main()方法中第一个read()和和第二个read();是可以顺利执行完的…

百度地图动态显示查询结构

<script type"text/javascript">// 百度地图API功能function G(id) {return document.getElementById(id);}var map new BMap.Map("l-map");map.centerAndZoom("北京",12); // 初始化地图,设置城市和地图级别。var ac …

solr5.0mysql_ik扩展支持Solr配置详解

扩展ik原生代码&#xff1a;public class IKAnalyzerTokenizerFactory extends TokenizerFactory{private boolean useSmart;public boolean useSmart(){return this.useSmart;}public void setUseSmart(boolean useSmart) {this.useSmart useSmart;}public IKAnalyzerTokeniz…

apache htpasswd.exe创建密码

一、使用apache htpasswd.exe创建密码文件&#xff0c;命令请看PHP推荐教程&#xff1a;apache htpasswd命令用法详解 apache htpasswd命令用法实例 1、如何利用htpasswd命令添加用户&#xff1f; 在apache安装目录bin下找到htpasswd #usr/local/apache/bin/htpasswd -bc .pass…

考研复试考java_2019考研复试经验帖:过来人谈5件“小事”

关于复试&#xff0c;决定这你的命运&#xff0c;考生一定要好好把握。关于复试&#xff0c;你做好前期功课&#xff0c;足够了解了吗?下面新东方在线分享一位过来人的经验之谈&#xff0c;给大家最走心的忠告~~▶先来说说复试规则。在复试之前学校会公布学校的复试分数线&…

Hadoop2源码分析-RPC机制初识

1.概述 上一篇博客&#xff0c;讲述Hadoop V2的序列化机制&#xff0c;这为我们学习Hadoop V2的RPC机制奠定了基础。RPC的内容涵盖的信息有点多&#xff0c;包含Hadoop的序列化机制&#xff0c;RPC&#xff0c;代理&#xff0c;NIO等。若对Hadoop序列化不了解的同学&#xff0c…

svn客户端 java_svn纯java客户端SVNKit学习整理(转)

http://www.iteye.com/topic/688217http://blog.csdn.net/feiren127/article/details/7551782把svnkit.jar添加到项目中&#xff0c;用于实现svn功能。 把jackson-all-1.6.2.jar添加到项目中&#xff0c;用于显示树列表。把javaee.ar添加到项目中。新建一个类(SVNUtil.class)实…

贪心 BestCoder Round #39 1001 Delete

题目传送门 1 /*2 贪心水题&#xff1a;找出出现次数>1的次数和res&#xff0c;如果要减去的比res小&#xff0c;那么总的不同的数字tot不会少&#xff1b;3 否则再在tot里减去多余的即为答案4 用set容器也可以做&#xff0c;思路一样5 */6 #include &l…

java this() super()_java中的this和super

this对象本身。public class ThisTest {ThisTest tTest;public ThisTest(){tTest this;}public void test(){System.out.println(this);}public static void main(String arg[]){new ThisTest().test();}}成员方法引用。成员变量引用。public class ThisTest {String name;Str…

配置汇编环境:使用vs2010+MASM

1、将MASM32下载并安装到根目录&#xff08;得到include和lib文件夹&#xff09;&#xff0c;官网即可下载&#xff0c;有64位版本2、配置vs2010 &#xff08;1&#xff09;添加项目 a、新建空白解决方案 b、添加空项目 c、项目属性->生成自定义-&g…

java 抽象类命名_Java的抽象类和接口

一.抽象类首先看抽象方法&#xff1a;抽象方法只有方法签名&#xff0c;没有方法的实现。并且被abstract修饰。 例如&#xff1a; abstract void test();有抽象方法的类只能被定义为抽象类&#xff0c;抽象类里可以没有抽象方法。抽象类的规则&#xff1a;抽象类必须使用abstr…

JSP、Servlet中get请求和post请求的区别总结

在学习JavaWeb最初的开始阶段&#xff0c;大家都会遇到HttpServlet中的doGet和doPost方法。前两天看《Head First Servlets & JSP》看到其中讲关于Servlet中get请求和post请求的区别&#xff0c;现总结如下&#xff1a; 1&#xff1a;请求数据的大小不同。 因为get请求的数…

用java解决约瑟夫循环问题_Java采用循环链表结构求解约瑟夫问题

本文实例讲述了Java采用循环链表结构求解约瑟夫问题的方法。分享给大家供大家参考。具体分析如下&#xff1a;这是第一次java考试的试题&#xff0c;对于没看过链表的同学来说就不会做&#xff0c;现在回头看看&#xff0c;还真不难。约瑟夫问题&#xff1a;有n个人&#xff0c…

在ubuntu上搭建开发环境9---Ubuntu删除ibus出现的问题及解决

删除 ibus输入法&#xff1a;  sudo apt-get install ibus 我们会遇到下面的问题 Ubuntu 14.04 系统设置很多选项消失。 其实遇到这个问题的一个最主要的原因是之前执行过卸载ibus输入法的操作&#xff0c;所以为了避免这个问题请不要卸载ibus输入法&#xff0c;大家依然可以…

java制作图形界面数据库_java图形界面以及链接数据库

import java、awt、*;import java、awt、event、*;import javax、swing、*;import java、sql、*;public class NoteTextArea extends JFrame implements ActionListener{private JPanel jpnew JPanel();private JButton[] jb new JButton[4];private JComboBox box;private JT…

HDU 3951 (博弈) Coin Game

先考虑两种简单的情况&#xff1a; 如果先手能一次把硬币拿完&#xff0c;即 k > n &#xff0c;那么先手胜如果每次只能拿一个硬币&#xff0c; 即 k 1 &#xff0c;那么如果有奇数个硬币先手胜&#xff0c;如果有偶数个硬币后手胜。剩下的情况就是先手一次拿不完&#xf…