【bz2594】水管局长数据加强版

题意:

给出一张n节点、m条代权无向边的无向联通图 和q个任务

1:询问一条x到y的路径 并使路径上最大权值最小 要求输出路径上最大权值

2:宣布x到y的路径报废题目保证该图永远联通

题解:

这是道凶残的题目 用了我一整天的时间

虽然AK大神表示这是模板题看到最大权值最小 可能会想到二分(其实我是写题解的时候才想到的 因为大表讲课的时候讲过怎么做)

但是好像二分不好判断是否可行 要判断貌似要O(m)的时间 对这个庞大的数据是很难A的于是

我们可以倒着来做 从最后一个任务开始

显然 若是要x到y最大值最小 就要保证图为最小生成树 并用动态树维护 路径上的最大值

任务1就直接从动态树上取答案

任务2 就添加一个水管 为了保证是最小生成树 算出x到y的最大值

如果比当前水管权值大 那么删掉最大的那个水管 并且link(x,y)

这题目虽然给了25s的时限 但是它竟然连输入都要优化 可见卡时卡得多凶残 这也体现了打动态树要打好常数的重要性

这题我TLE了一晚上 打了AK大神说的二分优化 但是还是T 当时已经快崩溃了 打了一天就做了一题还TLE(不难发现我后面的代码二分用的是wtf - -) 一气之下往全部函数前面加了个inline 又交了一次 本来不打算A的 但是它竟然过了 而且还是26s过的... 反正它是显示accept了... 话说JY大神优化了一晚上 刷到了第三名 9s!orz

代码:

  1 #include <cstdio>
  2 #include <map>
  3 #include <algorithm>
  4 using std::sort;
  5 using std::map;
  6 struct info{
  7        int lc,rc,fat,max,key,tag,root;
  8        info(const int a=0,const int b=0,const int c=0,const int d=0,const int e=0,const int f=0,const int g=1):
  9                   lc(a),rc(b),fat(c),max(d),key(e),tag(f),root(g){}
 10 }tree[200001];
 11 struct inli{
 12        int x,y,lll;
 13        inli(const int a=0,const int b=0,const int c=0):
 14                   x(a),y(b),lll(c){}
 15 }line[1000001],ask[100001];
 16 inline bool operator <(inli a,inli b){
 17        return a.x<b.x || (a.x==b.x && a.y<b.y);
 18 }
 19 //map<inli,int> ma;
 20 int n,m,q,nn,nb,lon[1000001],bo[100001],ans[100001],na,ma[2000001];
 21 inline void clean(){
 22      tree[0]=info(0,0,0,0,0,0,0);
 23 }
 24 inline void swap(int &a,int &b){
 25      int x=a;
 26      a=b,b=x;
 27 }
 28 inline void pushdown(int t){
 29      if (tree[t].tag){
 30                       tree[t].tag=0;
 31                       tree[tree[t].lc].tag^=1;
 32                       tree[tree[t].rc].tag^=1;
 33                       swap(tree[t].lc,tree[t].rc);
 34      }
 35      clean();
 36 }
 37 inline void maintain(int t){
 38      tree[t].max=t;
 39      int ll=tree[t].lc,rr=tree[t].rc;
 40      if (tree[tree[ll].max].key>tree[tree[t].max].key) tree[t].max=tree[ll].max;
 41      if (tree[tree[rr].max].key>tree[tree[t].max].key) tree[t].max=tree[rr].max;
 42 }
 43 inline void left(int t){
 44      int fa=tree[t].fat,r=tree[t].rc;
 45      tree[t].rc=tree[r].lc;
 46      tree[tree[r].lc].fat=t;
 47      tree[r].lc=t;
 48      tree[t].fat=r;
 49      if (tree[t].root) tree[t].root=0,tree[r].root=1;
 50      else if (tree[fa].lc==t) tree[fa].lc=r;
 51           else tree[fa].rc=r;
 52      tree[r].fat=fa;
 53      clean();
 54      maintain(t);
 55      maintain(r);
 56 }
 57 inline void right(int t){
 58      int fa=tree[t].fat,l=tree[t].lc;
 59      tree[t].lc=tree[l].rc;
 60      tree[tree[l].rc].fat=t;
 61      tree[l].rc=t;
 62      tree[t].fat=l;
 63      if (tree[t].root) tree[t].root=0,tree[l].root=1;
 64      else if (tree[fa].lc==t) tree[fa].lc=l;
 65           else tree[fa].rc=l;
 66      tree[l].fat=fa;
 67      clean();
 68      maintain(t);
 69      maintain(l);
 70 }
 71 inline void splay(int t){
 72      while (!tree[t].root){
 73            int fa=tree[t].fat,gr=tree[fa].fat;
 74            pushdown(gr);
 75            pushdown(fa);
 76            pushdown(t);
 77            if (tree[fa].root){
 78                               if (tree[fa].lc==t) right(fa);
 79                               else left(fa);
 80            }else if (tree[gr].lc==fa){
 81                     if (tree[fa].lc==t) right(gr),right(fa);
 82                     else left(fa),right(gr);
 83                  }else if (tree[fa].rc==t) left(gr),left(fa);
 84                        else right(fa),left(gr);
 85      }
 86 }
 87 inline void access(int x){
 88      int y;
 89      for (y=x,x=0;y;x=y,y=tree[y].fat){
 90          splay(y);
 91          pushdown(y);
 92          tree[tree[y].rc].root=1;
 93          tree[y].rc=x;
 94          tree[x].root=0;
 95          maintain(y);
 96      }
 97 }
 98 inline void makeroot(int t){
 99      access(t);
100      splay(t);
101      tree[t].tag^=1;
102 }
103 inline void link(int xx,int yy){
104      makeroot(xx);
105      splay(xx);
106      splay(yy);
107      pushdown(yy);
108      tree[tree[yy].rc].root=1;
109      tree[yy].rc=xx;
110      tree[xx].fat=yy;
111      tree[xx].root=0;
112      maintain(yy);
113 }
114 inline void cutting(int t){
115      splay(t);
116      pushdown(t);
117      int l=tree[t].lc,r=tree[t].rc;
118      if (l) tree[l].fat=tree[t].fat,tree[l].root=1;
119      if (r) tree[r].fat=0,tree[r].root=1;
120 }
121 inline void cutlink(int xx,int yy,int lo){
122      makeroot(xx);
123      access(yy);
124      splay(yy);
125      int save=tree[yy].max;
126      if (tree[save].key<=lo) return;
127      cutting(save);
128      tree[save]=info(0,0,0,save,lo,0,1);
129      link(save,xx);
130      link(save,yy);
131 }
132 inline int getfat(int t){
133     while (tree[t].fat) t=tree[t].fat;
134     return t;
135 }
136 inline bool check(int xx,int yy){
137      makeroot(xx);
138      access(yy);
139      splay(yy);
140      return getfat(xx)==yy;
141 }
142 inline int wtf(inli t){
143     int l=0,r=m,mid;
144     while (l<r-1){
145           mid=(l+r)/2;
146           if (line[mid]<t) l=mid;
147           else r=mid;
148     }
149     return r;
150 }
151 inline void build(){
152      for (int i=1;i<=n;i++) tree[i]=info(0,0,0,i,0,0,1);
153      nn=n;
154      for (int i=1;i<=m;i++){
155          int save=wtf(line[i]);
156          if (!ma[save]){
157                        if (check(line[i].x,line[i].y)) cutlink(line[i].x,line[i].y,lon[i]);
158                        else{
159                             ++nn;
160                             tree[nn]=info(0,0,0,nn,lon[i],0,1);
161                             link(nn,line[i].x);
162                             link(nn,line[i].y);
163                        }
164          }else ask[ma[save]].lll=lon[i];
165      }
166 }
167 inline int getint(){
168     char ch = getchar();
169     for ( ; ch > '9' || ch < '0'; ch = getchar());
170     int tmp = 0;
171     for ( ; '0' <= ch && ch <= '9'; ch = getchar())
172       tmp = tmp * 10 + int(ch) - 48;
173     return tmp;
174  } 
175 int main(){
176     freopen("tube.in","r",stdin);
177     freopen("bz2594.out","w",stdout);
178     int i,j,xx,yy;
179     scanf("%d%d%d
",&n,&m,&q);
180     for (i=1;i<=m;i++){
181         xx=getint();
182         yy=getint();
183         lon[i]=getint();
184         if (xx>yy) swap(xx,yy); 
185         line[i]=inli(xx,yy,lon[i]);
186     }
187     sort(line+1,line+m+1);
188     for (i=1;i<=m;i++) lon[i]=line[i].lll;
189     for (i=1;i<=q;i++){
190         bo[i]=getint();
191         xx=getint();
192         yy=getint();
193         if (xx>yy) swap(xx,yy);
194         ask[i]=inli(xx,yy);
195         if (bo[i]==2) ma[wtf(ask[i])]=i;
196     }
197     build();
198     for (i=q;i;i--){
199         if (i==1){
200                   i=1;
201         }
202         xx=ask[i].x,yy=ask[i].y;
203         if (bo[i]==1){
204                       makeroot(xx);
205                       access(yy);
206                       splay(yy);
207                       ans[++na]=tree[tree[yy].max].key;
208         }else cutlink(xx,yy,ask[i].lll);
209     }
210     for (i=na;i;i--) printf("%d
",ans[i]);
211 }
View Code
原文地址:https://www.cnblogs.com/g-word/p/3691744.html