<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      bzoj 2594

      很好的一道LCT題目

      首先我們可以發現,題目要求的就是最小生成樹上的一條樹鏈的最長邊的長度,因此我們實際只需動態維護最小生成樹即可

      然后我們考慮怎么動態維護最小生成樹

      不難發現,如果涉及在最小生成樹上刪邊,那么這個操作將變得非常復雜,因為我們并不知道刪邊之后要把什么樣的邊補充回去才行

      但是,如果我們倒序操作,把刪邊變成加邊,那么這個操作就變得相對簡單了

      回到本題,首先,我們把一定不會刪的邊建成一棵最小生成樹(或者一個森林?),這就是我們的初始狀態

      然后,倒序操作,每次把刪邊變為加邊,這樣每次加入一條邊時,我們只需討論這兩個點原先是否聯通即可

      如果兩個點原先就聯通,那么我們就找到這兩個點所在聯通塊里邊權最大的邊,刪去那條邊之后加入這條新來的邊即可

      但是LCT難以維護邊權,因此我們對每條邊虛擬一個有點權的點,加邊時把邊的兩個端點連到這個點上即可

      刪邊同理

      注意維護邊的編號

      貼代碼:

      (這個東西由于常數過于巨大在bzoj上過不去,但是luogu上的數據減弱版能過)

      #include <cstdio>
      #include <cmath>
      #include <cstring>
      #include <cstdlib>
      #include <iostream>
      #include <algorithm>
      #include <queue>
      #include <stack>
      #include <map>
      using namespace std;
      struct Ques
      {
          int x,y,typ,num;
      }q[1000005];
      struct Edge
      {
          int l,r,v;
          friend bool operator < (Edge a,Edge b)
          {
              return a.v<b.v;
          }
      }edge[1000005];
      map <pair<int,int>,int> M;
      int n,m,Q;
      int ch[2000005][2];
      int vis[2000005];
      int maxx[2000005];
      int val[2000005];
      int f[2000005];
      int fl[2000005];
      int ret[2000005];
      void update(int x)
      {
          maxx[x]=val[x];
          if(edge[maxx[ch[x][0]]].v>edge[maxx[x]].v)maxx[x]=maxx[ch[x][0]];
          if(edge[maxx[ch[x][1]]].v>edge[maxx[x]].v)maxx[x]=maxx[ch[x][1]];
      }
      bool be_root(int x)
      {
          if(ch[f[x]][0]==x||ch[f[x]][1]==x)return 0;
          return 1;
      }
      void pushdown(int x)
      {
          if(fl[x])
          {
              swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
              swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
              fl[ch[x][0]]^=1,fl[ch[x][1]]^=1;
              fl[x]=0;
          }
      }
      void repush(int x)
      {
          if(!be_root(x))repush(f[x]);
          pushdown(x);
      }
      void rotate(int x)
      {
         int y=f[x],z=f[y],k=(ch[y][1]==x);
          if(!be_root(y))ch[z][ch[z][1]==y]=x;
          f[x]=z;
          ch[y][k]=ch[x][!k],f[ch[x][!k]]=y;
          ch[x][!k]=y,f[y]=x;
          update(y),update(x);
      }
      void splay(int x)
      {
          repush(x);
          while(!be_root(x)&&x)
          {
              int y=f[x],z=f[y];
              if(!be_root(y)&&y)
              {
                  if((ch[y][1]==x)^(ch[z][1]==y))rotate(x);
                  else rotate(y);
              }
              rotate(x);
          }
          update(x);
      }
      void access(int x)
      {
          int y=0;
          while(x)
          {
              splay(x);
              ch[x][1]=y;
              update(x);
              y=x,x=f[x];
          }
      }
      void makeroot(int x)
      {
          access(x),splay(x);
          swap(ch[x][0],ch[x][1]),fl[x]^=1;
      }
      void link(int x,int y)
      {
          makeroot(x);
          f[x]=y;
      }
      void split(int x,int y)
      {
          makeroot(x),access(y),splay(y);
      }
      void cut(int x,int y)
      {
          split(x,y),ch[y][0]=f[x]=0,update(y);
      }
      int findf(int x)
      {
          access(x),splay(x),pushdown(x);
          while(ch[x][0])x=ch[x][0],pushdown(x);
          return x;
      }
      inline int read()
      {
          int f=1,x=0;char ch=getchar();
          while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
          while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
          return x*f;
      }
      int main()
      {
          n=read(),m=read(),Q=read();
          for(int i=1;i<=m;i++)
          {
              edge[i].l=read(),edge[i].r=read(),edge[i].v=read();
              if(edge[i].l>edge[i].r)swap(edge[i].l,edge[i].r);
          }
          sort(edge+1,edge+m+1);
          for(int i=1;i<=m;i++)M[make_pair(edge[i].l,edge[i].r)]=i;
          for(int i=1;i<=Q;i++)
          {
              q[i].typ=read(),q[i].x=read(),q[i].y=read();
              if(q[i].x>q[i].y)swap(q[i].x,q[i].y);
              if(q[i].typ==2)
              {
                  int t=M[make_pair(q[i].x,q[i].y)];
                  q[i].num=t,vis[t]=1;
              }
          }
          for(int i=1;i<=m;i++)maxx[i+n]=val[i+n]=i;
          for(int i=1;i<=m;i++)
          {
              if(vis[i])continue;
              int f1=findf(edge[i].l),f2=findf(edge[i].r);
              if(f1==f2)continue;
              link(edge[i].l,i+n),link(edge[i].r,i+n);
          }
          int temp=Q;
          while(Q)
          {
              if(q[Q].typ==1)
              {
                  split(q[Q].x,q[Q].y);
                  ret[Q]=edge[maxx[q[Q].y]].v;
              }else
              {
                  split(q[Q].x,q[Q].y);
                  int t=maxx[q[Q].y];
                  if(edge[q[Q].num].v<edge[maxx[q[Q].y]].v)
                  {
                      cut(edge[t].l,t+n); 
                      cut(edge[t].r,t+n);
                      link(edge[q[Q].num].l,q[Q].num+n);
                      link(edge[q[Q].num].r,q[Q].num+n);
                  }
              }
              Q--;
          }
          for(int i=1;i<=temp;i++)if(q[i].typ==1)printf("%d\n",ret[i]);
          return 0;
      }

       

      posted @ 2019-07-10 16:12  lleozhang  Views(174)  Comments(0)    收藏  舉報
      levels of contents
      主站蜘蛛池模板: 亚洲人成网站在线无码| 日韩在线视频线观看一区| 日韩精品区一区二区三vr| 99久久精品国产熟女拳交| 亚洲第一福利网站在线观看| jk白丝喷浆| 久久精品国产久精国产一老狼 | 日韩精品亚洲专在线电影| 亚洲欧美激情在线一区| 国产人妻精品午夜福利免费| 窝窝午夜色视频国产精品破| 国产毛片精品一区二区色| 国产精品成人av电影不卡| 九九热精品在线观看| 免费观看全黄做爰大片国产| 国产三级国产精品国产专| 无码人妻精品一区二区三区下载| 欧美性群另类交| 男女xx00xx的视频免费观看| 亚洲中文字幕无码专区| 久久精品国产午夜福利伦理| 久久精品国产亚洲AⅤ无码| 亚洲一区二区乱码精品| 在线aⅴ亚洲中文字幕| 四虎成人精品永久免费av| 影音先锋啪啪av资源网站| 亚洲AV国产福利精品在现观看| 亚洲国产综合精品2020| 中文字幕无码视频手机免费看| 强奷白丝美女在线观看| 亚洲精品成人区在线观看 | 深夜免费av在线观看| 色猫咪av在线网址| 日本一区二区三区免费播放视频站| 久久本道综合久久伊人| 国产精品中文字幕二区| 国产福利视频区一区二区| 美日韩精品一区三区二区| 极品少妇xxxx| 亚洲一区二区av在线| 丰满无码人妻热妇无码区 |