zoukankan      html  css  js  c++  java
  • bzoj 2594: [Wc2006]水管局长数据加强版

    Description

    SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的路径,接着通过信息化的控制中心通知路径上的水管进入准备送水状态,等到路径上每一条水管都准备好了,供水公司就可以开始送水了。嘟嘟一次只能处理一项送水任务,等到当前的送水任务完成了,才能处理下一项。
    在处理每项送水任务之前,路径上的水管都要进行一系列的准备操作,如清洗、消毒等等。嘟嘟在控制中心一声令下,这些水管的准备操作同时开始,但由于各条管道的长度、内径不同,进行准备操作需要的时间可能不同。供水公司总是希望嘟嘟能找到这样一条送水路径,路径上的所有管道全都准备就绪所需要的时间尽量短。嘟嘟希望你能帮助他完成这样的一个选择路径的系统,以满足供水公司的要求。另外,由于MY市的水管年代久远,一些水管会不时出现故障导致不能使用,你的程序必须考虑到这一点。
    不妨将MY市的水管网络看作一幅简单无向图(即没有自环或重边):水管是图中的边,水管的连接处为图中的结点。

    解题报告

    LCT维护最小生成树板子题,思路比较简单
    考虑一条边的两端的节点 (x,y) ,如果还没有连通,那么直接连边,如果已经连通,就与路径 ((x,y)) 上最大边比较,如果可以替换掉,那么就断掉最大边,加上当前边即可
    另外,维护边权考虑拆边为点,然后就当点权处理即可。这一题是删边,可以考虑把询问反过来建边,注意刚开始的边不能用LCT维护,直接kruskal做一遍即可,加强版卡常

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <map>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=200005,M=2000005;
    int gi(){
       int str=0;char ch=getchar();
       while(ch>'9' || ch<'0')ch=getchar();
       while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
       return str;
    }
    int n,m,Q,totnode=0,ans[N];
    struct node{int x,y,dis,b,id;}e[M/2],kru[M/2];
    struct Question{int flag,x,y;}q[N];
    map<int,int>mp[N];
    int fa[M],ch[M][2],maxid[M],id[M],par[N];bool rev[M],app[M];
    il int find(int x){return par[x]==x?x:par[x]=find(par[x]);}
    il bool isrt(int x){return (ch[fa[x]][0]!=x && ch[fa[x]][1]!=x);}
    il void upd(int r){
       int ls=ch[r][0],rs=ch[r][1];maxid[r]=id[r];
       if(e[maxid[ls]].dis>e[maxid[r]].dis)maxid[r]=maxid[ls];
       if(e[maxid[rs]].dis>e[maxid[r]].dis)maxid[r]=maxid[rs];
    }
    il void rotate(RG int r){
       int y=fa[r];bool t=(ch[y][1]==r);
       ch[y][t]=ch[r][!t];
       fa[ch[y][t]]=y;
       ch[r][!t]=y;
       fa[r]=fa[y];
       if(!isrt(y))ch[fa[y]][ch[fa[y]][1]==y]=r;
       fa[y]=r;
       upd(y);upd(r);
    }
    il void pushdown(RG int r){
       if(!rev[r])return ;
       int ls=ch[r][0],rs=ch[r][1];
       rev[ls]^=1;rev[rs]^=1;
       swap(ch[ls][0],ch[ls][1]);swap(ch[rs][0],ch[rs][1]);
       rev[r]=0;
    }
    il void Push(RG int r){
       if(!isrt(r) && r)Push(fa[r]);
       pushdown(r);
    }
    il void splay(RG int r){
       Push(r);
       while(!isrt(r)){
          int y=fa[r],p=fa[y];
          if(isrt(y))rotate(r);
          else if((ch[p][0]==y)==(ch[y][0]==r))rotate(y),rotate(r);
          else rotate(r),rotate(r);
       }
    }
    il void access(RG int x){
       RG int y=0;
       while(x){
          splay(x);
          ch[x][1]=y;upd(x);
          x=fa[y=x];
       }
    }
    il void mroot(int x){access(x);splay(x);rev[x]^=1;swap(ch[x][0],ch[x][1]);}
    il int query(int x,int y){mroot(x);access(y);splay(y);return e[maxid[y]].dis;}
    il void link(int x,int y){mroot(x);fa[x]=y;upd(y);}
    il void cut(int x,int y){
       mroot(x);access(y);splay(y);
       fa[x]=ch[y][0]=0;upd(y);
    }
    il void updata(int x,int y){
       int i=mp[x][y];int b=e[i].b;
       if(find(x)==find(y)){
          mroot(x);access(y);splay(y);
          int j=maxid[y];
          if(e[j].dis<=e[i].dis)return ;
          cut(e[j].x,e[j].b);cut(e[j].y,e[j].b);
          link(b,x);link(y,b);
       }
       else{
          par[find(y)]=find(x);
          link(b,x);link(y,b);
       }
    }
    il bool comp(const node &i,const node &j){return i.dis<j.dis;}
    void work()
    {
       scanf("%d%d%d",&n,&m,&Q);totnode=n;
       for(RG int i=1;i<=n;i++)par[i]=i;
       for(RG int i=1;i<=m;i++){
          e[i].x=gi();e[i].y=gi();e[i].dis=gi();e[i].b=++totnode;
          if(e[i].x>e[i].y)swap(e[i].x,e[i].y);
          mp[e[i].x][e[i].y]=i;id[totnode]=i;e[i].id=i;
          kru[i]=e[i];
       }
       for(RG int i=1;i<=Q;i++){
          q[i].flag=gi();q[i].x=gi();q[i].y=gi();
          if(q[i].x>q[i].y)swap(q[i].x,q[i].y);
          if(q[i].flag==2)app[mp[q[i].x][q[i].y]]=true;
       }
       int x,y,totedge=0;
       sort(kru+1,kru+m+1,comp);
       for(RG int i=1;i<=m;i++){
          if(app[kru[i].id])continue;
          x=kru[i].x;y=kru[i].y;
          if(find(x)==find(y))continue;
          totedge++;par[find(y)]=find(x);
          link(kru[i].b,x);link(y,kru[i].b);
          if(totedge==n-1)break;
       }
       for(RG int i=Q;i>=1;i--){
          if(q[i].flag==1)ans[i]=query(q[i].x,q[i].y);
          else updata(q[i].x,q[i].y);
       }
       for(RG int i=1;i<=Q;i++)if(q[i].flag==1)printf("%d
    ",ans[i]);
    }
    
    int main(){work();return 0;}
    
    
  • 相关阅读:
    cp备份操作时如何忽略指定的目录
    Wordpress“固定链接”页面出现404原因及解决方法
    CentOS7上搭建WEB服务器
    坑爹的云服务安全组
    java spring hibernate
    电脑性能
    android subclipse subversive
    android 开发 程序中下载安装APK文件 问题汇总 解析程序包时出现问题
    android sqlite datetime demo
    android SurfaceView中播放视频 按视频的原始比例播放
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7647770.html
Copyright © 2011-2022 走看看