P4172 [WC2006]水管局長
阿新 • • 發佈:2018-12-26
P4172 [WC2006]水管局長
前言
luogu資料太小
去bzoj,他的資料大一些
思路
正著刪不好維護
那就倒著加,沒了
LCT維護他的最小生成樹MST
樹上加一條邊肯定會有一個環
看看環上最大值和加邊的大小
然後選擇加不加,改不改
錯誤
哇,噁心撒
懟著題解都寫不出來
最後亂改了一下就A了???
程式碼
// luogu-judger-enable-o2 #include <bits/stdc++.h> #define ls ch[x][0] #define rs ch[x][1] #define FOR(i,a,b) for(int i=a;i<=b;++i) using namespace std; const int N=1e6+7; const int inf=0x3f3f3f3f; int read() { int x=0,f=1;char s=getchar(); for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1; for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0'; return x*f; } int n,m,qwq,ans[N]; map<int,int> MVP[N]; //MVP[1200][1200]; luogu struct node { int u,v,q,id; bool operator < (const node &b) const { return q<b.q; } }G[N]; map<pair<int,int>,int> mdzz; struct query { int opt,x,y,id; }Q[N]; int f[N],ch[N][2],s[N],lazy[N]; int val[N]; void pushup(int x) { s[x]=x; if(val[s[ls]] > val[s[x]]) s[x]=s[ls]; if(val[s[rs]] > val[s[x]]) s[x]=s[rs]; } void tag(int x) { swap(ls,rs); lazy[x]^=1; } bool isroot(int x) { return ch[f[x]][0]==x || ch[f[x]][1]==x; } void pushdown(int x) { if(lazy[x]) { if(ls) tag(ls); if(rs) tag(rs); lazy[x]=0; } } void rotate(int x) { int y=f[x],z=f[y],k=ch[y][1]==x,m=ch[x][k^1]; if(isroot(y)) ch[z][ch[z][1]==y]=x; ch[x][k^1]=y; ch[y][k]=m; if(m) f[m]=y; f[x]=z; f[y]=x; pushup(y); } int q[N]; void splay(int x) { int y=x,z=0; q[++z]=y; while(isroot(y)) q[++z]=y=f[y]; while(z) pushdown(q[z--]); while(isroot(x)) { y=f[x],z=f[y]; if(isroot(y)) (ch[y][1]==x)^(ch[z][1]==y) ? rotate(x) : rotate(y); rotate(x); } pushup(x); } void access(int x) { for(int y=0;x;y=x,x=f[x]) splay(x),rs=y,pushup(x); } void makeroot(int x) { access(x); splay(x); tag(x); } int findroot(int x) { access(x); splay(x); while(ls) pushdown(x),x=ls; return x; } int split(int x,int y) { makeroot(x); access(y); splay(y); return s[y]; } void link(int x,int y) { makeroot(x); if(findroot(y)!=x) f[x]=y; } void cut(int x,int y) { makeroot(x); if(findroot(y)==x&&f[x]==y&&!ch[x][1]) { f[x]=ch[y][0]=0; pushup(y); } } int suanle_f[N],suanle_siz[N]; int suanle_find(int x) { return suanle_f[x]==x ? x : suanle_f[x]=suanle_find(suanle_f[x]); } void suanle_uu(int x,int y) { int fx=suanle_find(x),fy=suanle_find(y); if(suanle_siz[fx] <= suanle_siz[fy]) { suanle_f[fx]=fy; if(suanle_siz[fx]==suanle_siz[fy]) suanle_siz[fy]++; } else { suanle_f[fy]=fx; } } int main() { // freopen("a.in","r",stdin); // freopen("a.out","w",stdout); n=read(),m=read(),qwq=read(); FOR(i,1,m) suanle_f[i]=i; FOR(i,1,m) { G[i].u=read(),G[i].v=read(),G[i].q=read(); if(G[i].u>G[i].v)swap(G[i].u,G[i].v); } sort(G+1,G+1+m); FOR(i,1,m) val[i+n]=G[i].q,mdzz[make_pair(G[i].u,G[i].v)]=i,s[n+i]=n+i; FOR(i,1,qwq) { Q[i].opt=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].opt==2) { Q[i].id=mdzz[make_pair(Q[i].x,Q[i].y)]; MVP[Q[i].x][Q[i].y]=1; } } FOR(i,1,m) val[i+n]=G[i].q; int js=0; FOR(i,1,m) { if(MVP[G[i].u][G[i].v]==1) continue; if(suanle_find(G[i].u)==suanle_find(G[i].v)) continue; link(G[i].u,i+n); link(G[i].v,i+n); suanle_uu(G[i].u,G[i].v); js++; if(js==n-1) break; } for(int i=qwq;i>=1;--i) { int x=Q[i].x,y=Q[i].y; if(Q[i].opt==1) { int tmp=split(x,y); ans[i]=val[tmp]; } else { int tmp=split(x,y); if(val[tmp] > G[Q[i].id].q) { cut(G[tmp-n].u,tmp); cut(G[tmp-n].v,tmp); link(x,Q[i].id+n); link(y,Q[i].id+n); } } } FOR(i,1,qwq) if(Q[i].opt==1) cout<<ans[i]<<"\n"; return 0; }