题目链接 洛谷(COGS上也有)

不想去做加强版了。。(其实处理一下矩阵就好了)

题意: 有一张图,求一条x->y的路径,使得路径上最长边尽量短并输出它的长度。会有<=5000次删边。

这实际上就是动态地维护MST。用LCT维护MST,路径询问也能直接查询,每次删边看这条边是否在MST上。

只有1000个点!边直接矩阵存。

而且删边次数很少,于是最初想的是每次删边用堆优化Prim O(nlogn)重新求一遍MST。但是\(5000*1000*10=5e7\)。。(也许行吧)

日常删边改成加边,离线即可。加边时MST上的求路径Max,看是否需要Cut,重新Link.(正序的话还要找一遍没被删的连接两集合的最小边)

#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define MAXIN (200000)
const int N=1005,M=1e5+5,S=N+M;//虽然维护的是MST但大小还是要M的。。当然可以记录每条树边并循环利用,以后再写吧。。 int n,m,type[M],ff[N],qx[M],qy[M],id[N][N],Ans[M];
char IN[MAXIN],*SS=IN,*TT=IN;
bool ban[M];
struct Edge{
int fr,to,val;
Edge() {}
Edge(int f,int t,int v):fr(f),to(t),val(v) {}
bool operator <(const Edge &a)const{
return val<a.val;
}
}e[M];
namespace LCT
{
#define lson son[x][0]
#define rson son[x][1] int pos[S],val[S],son[S][2],fa[S],sk[S];
bool rev[S];
inline int Get(int x,int y){
return val[x]>val[y]?x:y;
}
inline void Update(int x){
pos[x]=Get(x,Get(pos[lson],pos[rson]));//是左右儿子的pos!又一次写错。。
}
inline bool n_root(int x){
return son[fa[x]][0]==x||son[fa[x]][1]==x;
}
inline void Rev(int x){
std::swap(lson,rson), rev[x]^=1;
}
void PushDown(int x){
if(rev[x]) Rev(lson),Rev(rson),rev[x]=0;
}
void Rotate(int x)
{
int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
if(n_root(a)) son[b][son[b][1]==a]=x;
if(son[x][r]) fa[son[x][r]]=a;
fa[a]=x, fa[x]=b, son[a][l]=son[x][r], son[x][r]=a;
Update(a);
}
void Splay(int x)
{
int t=1,a=x; sk[1]=x;
while(n_root(a)) sk[++t]=a=fa[a];
while(t) PushDown(sk[t--]);
while(n_root(x))
{
if(n_root(a=fa[x])) Rotate(son[a][1]==x^son[fa[a]][1]==a?x:a);
Rotate(x);
}
Update(x);
}
void Access(int x){
for(int pre=0; x; x=fa[pre=x])
Splay(x), rson=pre, Update(x);
}
void Make_root(int x){
Access(x), Splay(x), Rev(x);
}
void Split(int x,int y){
Make_root(x), Access(y), Splay(y);
}
int Find_root(int x)
{
Access(x), Splay(x);
while(lson) x=lson;
return x;
}
void Link(int x){//在合法的情况下Find_root()并不是必须的(不维护子树信息的话?)
Make_root(e[x].to), fa[fa[e[x].to]=x+N]=e[x].fr;
val[x+N]=e[x].val, Update(x+N);
}
void Cut(int x){//注意这的编号
Access(e[x-N].to), Splay(x), lson=rson=fa[lson]=fa[rson]=0;
}
}
using namespace LCT; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
int Get_fa(int x){
return x==ff[x]?x:ff[x]=Get_fa(ff[x]);
} int main()
{
n=read(),m=read();int Q=read();
for(int x,y,i=1; i<=m; ++i) x=read(),y=read(),e[i]=Edge(x,y,read());
std::sort(e+1,e+1+m);//先排序再编号!
for(int i=1; i<=m; ++i) id[e[i].fr][e[i].to]=id[e[i].to][e[i].fr]=i;
for(int i=1; i<=Q; ++i)
{
type[i]=read(),qx[i]=read(),qy[i]=read();
if(type[i]==2) ban[id[qx[i]][qy[i]]]=1;
}
for(int i=1; i<=n; ++i) ff[i]=i;
for(int t,x,y,k=0,i=1; i<=m; ++i)
if(!ban[t=id[x=e[i].fr][y=e[i].to]] && Get_fa(x)!=Get_fa(y))
{//不需要记r1,r2
ff[ff[x]]=ff[y], Link(t);
if(++k==n) break;
}
int cnt=0;
for(int i=Q,x,y,t; i; --i)
{
Split(x=qx[i],y=qy[i]);
if(type[i]==1) Ans[++cnt]=val[pos[y]];
else if(t=id[x][y],val[pos[y]]>e[t].val){
Cut(pos[y]), Link(t);
}
}
while(cnt) printf("%d\n",Ans[cnt--]); return 0;
}

洛谷.4172.[WC2006]水管局长(LCT Kruskal)的更多相关文章

  1. 洛谷4172 WC2006水管局长(LCT维护最小生成树)

    这个题和魔法森林感觉有很相近的地方啊 同样也是维护一个类似最大边权最小的生成树 但是不同的是,这个题是有\(cut\)和询问,两种操作.... 这可如何是好啊? 我们不妨倒着来考虑,假设所有要\(cu ...

  2. 洛谷 4172 [WC2006]水管局长

    [题解] 我们把操作倒过来做,就变成了加边而不是删边.于是用LCT维护动态加边的最小生成树就好了.同样要注意把边权变为点权. #include<cstdio> #include<al ...

  3. 洛谷P4172 [WC2006]水管局长 (LCT,最小生成树)

    洛谷题目传送门 思路分析 在一个图中,要求路径上最大边边权最小,就不难想到最小生成树.而题目中有删边的操作,那肯定是要动态维护啦.直接上LCT维护边权最小值(可以参考一下蒟蒻的Blog) 这时候令人头 ...

  4. 洛谷P4172 [WC2006]水管局长(lct求动态最小生成树)

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

  5. [洛谷P4172] WC2006 水管局长

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

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

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

  7. luogu P4172 [WC2006]水管局长 LCT维护动态MST + 离线

    Code: #include<bits/stdc++.h> #define maxn 1200000 #define N 120000 using namespace std; char ...

  8. 【洛谷P4172】水管局长

    题目大意:给定 N 个点,M 条边的无向图,支持两种操作:动态删边和查询任意两点之间路径上边权的最大值最小是多少. 题解: 引理:对原图求最小生成树,可以保证任意两点之间的路径上边权的最大值取得最小值 ...

  9. P4172 [WC2006]水管局长(LCT)

    P4172 [WC2006]水管局长 LCT维护最小生成树,边权化点权.类似 P2387 [NOI2014]魔法森林(LCT) 离线存储询问,倒序处理,删边改加边. #include<iostr ...

随机推荐

  1. sublime3添加python编译系统

    好记性不如烂笔头 为sublime3添加python编译系统,这里使用的anonconda2中的python.exe(即python2.7版本) 步骤: (1)打开sublime,打开“工具-> ...

  2. Andrew Ng在coursera上的ML视频 知识点笔记(2)

    一.由线性回归导出逻辑回归: 二.“一对多”算法解决多分类问题: 三.“过拟合”和“欠拟合”: (1)对线性回归加入正则项: (2)对逻辑回归加入正则项: (3)加入正则项之后的正规方程:

  3. vim 超强发行版

    推荐第一个: https://github.com/spf13/spf13-vim https://github.com/Spacevim/Spacevim https://github.com/JB ...

  4. uoj#188. 【UR #13】Sanrd(Min_25筛)

    题面 传送门 题解 这是一道语文题 不难看出,题目所求即为\(l\)到\(r\)中每个数的次大质因子 我们考虑\(Min\_25\)筛的过程,设 \[S(n,j)=\sum_{i=1}^nsec_p( ...

  5. 020_秘钥管理服务器vault

    一. https://github.com/hashicorp/vault     #待研究

  6. Ex 3_25 图中每个顶点有一个相关价格..._十一次作业

    (a)首先对有向无环图进行拓扑排序,再按拓扑排序的逆序依次计算每个顶点的cost值,每个顶点的cost值为自身的price值与相邻顶点间的cost值得最小值 (b)求出图中的每一个强连通分量,并把所有 ...

  7. expdp和impdp 使用注意事项

    使用EXPDP和IMPDP时应该注意的事项: EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用. EXPDP和IMPDP是服务端的工具程序,他们只能在ORACLE服务端使用, ...

  8. Python-2d形变 动画 表格

    一.形变 /*1.形变参考点: 三轴交界点*/ transform-origin: x轴坐标 y轴坐标; /*2.旋转 rotate deg*/ transform: rotate(720deg); ...

  9. vue系列之核心思想

    1.数据驱动 只要改变数据,Vuejs会通过Directives指令对DOM进行封装,当数据发生变化,会通知相应的DOM进行变化 Vuejs会对DOM进行监听,通过DOMListeners监听视图的变 ...

  10. python 全栈开发,Day90(Vue组件,前端开发工具包)

    昨日内容回顾 1. Vue使用 1. 生成Vue实例和DOM中元素绑定 2. app.$el --> 取出该vue实例绑定的DOM标签 3. app.$data --> 取出该vue实例绑 ...