zoukankan      html  css  js  c++  java
  • [WC 2006] 水管局长数据加强版

    题解:
    很显然的是要用到kruskal算法,这样就能保证路径上的最大边权最小.
    我们可以采取离线的方法,将删边化为加边就好了.先用没有删过的边跑kruskal,这样剩下的边就可以丢掉了.然后从后往前做.
    对于操作一:直接询问即可,题目已经保证了两点相连了(想想为什么).
    对于操作二:我们对需要加的边(u,v)进行讨论.如果u和v没有连通,直接link操作.如果u和v已经连通了,但路径上的最大边权大于这条边的边权,那么我们先cut,在link.
    对于读取边信息的LCT,我们用的方法是对于一条边(u,v),建一个需点x,将边的信息存在x上,然后连接u和x以及v和x就可以了.

      1 #include<iostream>
      2 #include<cstdlib>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<cstring>
      7 #include<queue>
      8 #include<vector>
      9 #include<stack>
     10 #include<map>
     11 #define MAXN 2000010
     12 #define RG register
     13 #define LL long long int
     14 using namespace std;
     15 const int INF=1e9;
     16 const int mod=31011;
     17 typedef pair<int,int> pi;
     18 struct node{
     19   int x,y,z;int id;
     20 }t[MAXN];
     21 struct ed{
     22   int l,r,w;int vi;
     23 }e[MAXN];
     24 int n,m,Q;
     25 int ch[MAXN][2],mal[MAXN],fa[MAXN],rev[MAXN];
     26 int val[MAXN];
     27 int ans[MAXN];
     28 int q[MAXN],top;
     29 map<pi,int> p;
     30 int gi()
     31 {
     32   int x=0,f=1;char ch=getchar();
     33   while(ch<'0' || ch>'9'){ if(ch=='-') f*=-1;ch=getchar();}
     34   while(ch>='0'&&ch<='9'){ x=x*10+ch-'0';ch=getchar();}
     35   return x*f;
     36 }
     37 bool cmp(ed a,ed b){ return a.w<b.w;}
     38 bool isroot(int x){ return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
     39 void up(int x){
     40   int l=ch[x][0],r=ch[x][1];
     41   mal[x]=x;
     42   if(val[mal[l]]>val[mal[x]]) mal[x]=mal[l];
     43   if(val[mal[r]]>val[mal[x]]) mal[x]=mal[r];
     44 }
     45 void down(int x){
     46   if(rev[x])
     47     {
     48       swap(ch[x][0],ch[x][1]);
     49       rev[x]^=1;rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;
     50     }
     51 }
     52 void rotate(int x)
     53 {
     54   int old=fa[x],oldf=fa[old],rel=(ch[old][1]==x);
     55   if(!isroot(old))
     56     ch[oldf][ch[oldf][1]==old]=x;
     57   fa[x]=oldf;fa[ch[x][rel^1]]=old;ch[old][rel]=ch[x][rel^1];
     58   fa[old]=x;ch[x][rel^1]=old;
     59   up(old);up(x);
     60 }
     61 void splay(int x)
     62 {
     63   int old,oldf,now=x;top=0;q[++top]=now;
     64   while(!isroot(now)) q[++top]=fa[now],now=fa[now];
     65   while(top){ down(q[top]);top--;}
     66   while(!isroot(x))
     67     {
     68       old=fa[x];oldf=fa[old];
     69       if(!isroot(old))
     70     {
     71       if((ch[old][0]==x)||(ch[oldf][0]==old)) rotate(x);
     72       else rotate(old);
     73     }
     74       rotate(x);
     75     }
     76 }
     77 void access(int x){for(int t=0;x;t=x,x=fa[x]) splay(x),ch[x][1]=t,up(x);}
     78 void makeroot(int x){access(x);splay(x);rev[x]^=1;}
     79 int find(int x){access(x);splay(x);while(ch[x][0]) x=ch[x][0];return x;}
     80 void cut(int x,int y){makeroot(x);access(y);splay(y);if(ch[y][0]==x) ch[y][0]=fa[x]=0;}
     81 void link(int x,int y){makeroot(x);fa[x]=y;}
     82 int query(int x,int y){makeroot(x);access(y);splay(y); return mal[y];}
     83 int main()
     84 {
     85   //freopen("1.in","r",stdin);
     86   n=gi();m=gi();Q=gi();
     87   for(int i=1;i<=m;i++){
     88     e[i].l=gi();e[i].r=gi();e[i].w=gi();
     89    }  
     90   sort(e+1,e+m+1,cmp);
     91   for(int i=1;i<=m;i++){
     92     p[pi(e[i].l,e[i].r)]=i;p[pi(e[i].r,e[i].l)]=i;
     93     val[i+n]=e[i].w;mal[i+n]=i+n;
     94   }
     95   for(int i=1;i<=Q;i++)
     96     {
     97       t[i].z=gi();t[i].x=gi();t[i].y=gi();
     98       if(t[i].z==2){t[i].id=p[pi(t[i].x,t[i].y)];e[t[i].id].vi=1;}
     99     }
    100   for(int i=1;i<=m;i++)
    101     {
    102       if(e[i].vi==1) continue;
    103       if(find(e[i].l)!=find(e[i].r)){link(e[i].l,i+n),link(e[i].r,i+n);}
    104     }
    105   for(int i=Q;i>=1;i--)
    106     {
    107       if(t[i].z==1) ans[i]=val[query(t[i].x,t[i].y)];
    108       else {
    109     if(find(t[i].x)!=find(t[i].y)){ link(t[i].x,t[i].id+n);link(t[i].y,t[i].id+n);}
    110     else{
    111       int w=query(t[i].x,t[i].y);
    112       if(e[t[i].id].w<val[w]){
    113         cut(e[w-n].l,w);cut(e[w-n].r,w);link(t[i].x,t[i].id+n);link(t[i].y,t[i].id+n);
    114       }
    115     }
    116       }
    117     }
    118   for(int i=1;i<=Q;i++)
    119     if(t[i].z==1) printf("%d
    ",ans[i]);
    120   return 0;
    121 }
  • 相关阅读:
    ASP.NET 自制时间控件
    ORACLE 函数汇总之单记录函数
    Servers IIS 重启命令
    ASP.NET 两个Dropdownlist控件联动
    ASP.NET datagridview控件表头定义
    python Image 安装
    ssh 不需要密码的链接
    [Redis] redis 相关的博客
    [emacs] python代码折叠
    linux python 链接 oracle
  • 原文地址:https://www.cnblogs.com/Landlord-greatly/p/8098022.html
Copyright © 2011-2022 走看看