山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

bzoj 2594 [Wc2006]水管局长数据加强版(LCT+最小生成树)

 

【深坑勿入】

 

【给个链接】

 

  http://blog.csdn.net/popoqqq/article/details/41348549

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #define FOR(a,b,c) for(int a=b;a<=c;a++)
  6 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
  7 using namespace std;
  8 
  9 typedef long long ll;
 10 typedef unsigned int ul;
 11 const int N = 4e5+10;
 12 
 13 ll read() {
 14     char c=getchar();
 15     ll f=1,x=0;
 16     while(!isdigit(c)) {
 17         if(c=='-') f=-1; c=getchar();
 18     }
 19     while(isdigit(c))
 20         x=x*10+c-'0',c=getchar();
 21     return x*f;
 22 }
 23 
 24 struct Edge { 
 25     int u,v,w;
 26     bool operator < (const Edge& rhs) const {
 27         return u<rhs.u||(u==rhs.u&&v<rhs.v);
 28     }
 29 }e[N<<2];
 30 
 31 namespace LCT {
 32 
 33     struct Node {
 34         Node *ch[2],*fa;
 35         int rev,id,maxe;
 36         Node() ;
 37         void reverse() {
 38             rev^=1;
 39             swap(ch[0],ch[1]);
 40         }
 41         void up_push() {
 42             if(fa->ch[0]==this||fa->ch[1]==this) 
 43                 fa->up_push();
 44             if(rev) {
 45                 ch[0]->reverse();
 46                 ch[1]->reverse();
 47                 rev=0;
 48             }
 49         }
 50         void maintain() {
 51             int _max=-1;
 52             if(e[ch[0]->maxe].w>_max)
 53                 _max=e[ch[0]->maxe].w,maxe=ch[0]->maxe;
 54             if(e[ch[1]->maxe].w>_max)
 55                 _max=e[ch[1]->maxe].w,maxe=ch[1]->maxe;
 56             if(e[id].w>_max) maxe=id;
 57         }
 58     } *null=new Node,T[N],E[N<<2];
 59     Node::Node() {
 60         id=maxe=rev=0;
 61         fa=ch[0]=ch[1]=null;
 62     }
 63     
 64     void rot(Node* o,int d) {
 65         Node *p=o->fa;
 66         p->ch[d]=o->ch[d^1];
 67         o->ch[d^1]->fa=p;
 68         o->ch[d^1]=p;
 69         o->fa=p->fa;
 70         if(p==p->fa->ch[0])
 71             p->fa->ch[0]=o;
 72         else if(p==p->fa->ch[1])
 73             p->fa->ch[1]=o;
 74         p->fa=o;
 75         p->maintain();
 76     }
 77     void splay(Node *o) {
 78         o->up_push();
 79         Node *nf,*nff;
 80         while(o->fa->ch[0]==o||o->fa->ch[1]==o) {
 81             nf=o->fa,nff=nf->fa;
 82             if(o==nf->ch[0]) {
 83                 if(nf==nff->ch[0]) rot(nf,0);
 84                 rot(o,0);
 85             } else {
 86                 if(nf==nf->ch[1]) rot(nf,1);
 87                 rot(o,1);
 88             }
 89         }
 90         o->maintain();
 91     }
 92     void Access(Node* o) {
 93         Node *son=null;
 94         while(o!=null) {
 95             splay(o);
 96             o->ch[1]=son;
 97             o->maintain();
 98             son=o; o=o->fa;
 99         }
100     }
101     void evert(Node* o) {
102         Access(o);
103         splay(o);
104         o->reverse();
105     }
106     void Link(Node* u,Node* v) {
107         evert(u);
108         u->fa=v;
109     }
110     void Cut(Node* u,Node* v) {
111         evert(u);
112         Access(v); splay(v);
113         u->fa=v->ch[0]=null;
114         v->maintain();
115     }
116     Node* find(Node* o) {
117         while(o->fa!=null) o=o->fa;
118         return o;
119     }
120     
121 }
122 using namespace LCT;
123 
124 int n,m,q,flag[N],ans[N];
125 
126 struct Q { int op,x,y;
127 }que[N];
128 
129 int query(Node* u,Node* v)
130 {
131     if(find(u)!=find(v)) return 0;
132     evert(u);
133     Access(v),splay(v);
134     return v->maxe;
135 }
136 void insert(Node* u,Node* v,int id) 
137 {
138     if(find(u)==find(v)) {
139         int maxe=query(u,v);
140         if(e[maxe].w<=e[id].w) return ;
141         Cut(&E[maxe],&T[e[maxe].u]);
142         Cut(&E[maxe],&T[e[maxe].v]);
143     }
144     Link(&E[id],u);
145     Link(&E[id],v);
146 }
147 int search(Edge x)
148 {
149     int l=1,r=m,mid;
150     while(l<=r) {
151         mid=l+r>>1;
152         if((!(e[mid]<x))&&(!(x<e[mid]))) return mid;
153         if(x<e[mid]) r=mid-1;
154         else l=mid+1;
155     }
156     return 0;
157 }
158 
159 int main()
160 {
161     freopen("in.in","r",stdin);
162     freopen("out.out","w",stdout);
163     n=read(),m=read(),q=read();
164     FOR(i,0,m) E[i].maxe=E[i].id=i;
165     FOR(i,1,m) {
166         e[i].u=read(),e[i].v=read(),e[i].w=read();
167         if(e[i].u>e[i].v) swap(e[i].u,e[i].v);
168     }
169     e[0].w=0;
170     sort(e+1,e+m+1);
171     FOR(i,1,q) {
172         que[i].op=read(),que[i].x=read(),que[i].y=read();
173         if(que[i].x>que[i].y) swap(que[i].x,que[i].y);
174         if(que[i].op==2) {
175             int x=search((Edge){que[i].x,que[i].y,0});
176             if(x==0) puts("error");
177             flag[x]=1;
178         }
179     }
180     FOR(i,1,m) if(!flag[i]) {
181         insert(&T[e[i].u],&T[e[i].v],i);
182     }
183     for(int i=q;i;i--) {
184         if(que[i].op==2) {
185             int x=search((Edge){que[i].x,que[i].y,0});
186             insert(&T[e[x].u],&T[e[x].v],x);
187         } else {
188             ans[i]=e[query(&T[que[i].x],&T[que[i].y])].w;
189         }
190     }
191     FOR(i,1,q) if(que[i].op==1)
192         printf("%d\n",ans[i]);
193     return 0;
194 }
View Code

 

posted on 2016-03-26 18:35  hahalidaxin  阅读(301)  评论(0编辑  收藏  举报