1. 程式人生 > >luogu4172 [WC2006]水管局長

luogu4172 [WC2006]水管局長

als CI too cmp ID oid for air continue

就是用 lct 維護最小生成樹
ref

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
typedef pair<int,int> par;
int n, m, q, val[200005], zdz[200005], ans[200005], ch[200005][2];
int fa[200005];
bool vis[100005], rev[200005];
map<par,int> mp;
struct Edge{
    int
fro, too, val; }edge[100005]; struct Ques{ int opt, x, y; }qu[100005]; bool cmp(Edge x, Edge y){ return x.val<y.val; } bool isRoot(int x){ return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x; } int getW(int x){ return ch[fa[x]][1]==x; } void upd(int x){ zdz[x] = val[x]; if(edge[zdz[ch[x][0
]]].val>edge[zdz[x]].val) zdz[x] = zdz[ch[x][0]]; if(edge[zdz[ch[x][1]]].val>edge[zdz[x]].val) zdz[x] = zdz[ch[x][1]]; } void pushDown(int x){ if(rev[x]){ swap(ch[x][0], ch[x][1]); rev[ch[x][0]] ^= 1; rev[ch[x][1]] ^= 1; rev[x] = false; } } void
xf(int x){ if(fa[x]) xf(fa[x]); pushDown(x); } void rotate(int x){ int old=fa[x], oldf=fa[old], w=getW(x); if(!isRoot(old)) ch[oldf][ch[oldf][1]==old] = x; ch[old][w] = ch[x][w^1]; ch[x][w^1] = old; fa[ch[old][w]] = old; fa[ch[x][w^1]] = x; fa[x] = oldf; upd(old); upd(x); } void splay(int x){ xf(x); while(!isRoot(x)){ int f=fa[x]; if(!isRoot(f)) rotate(getW(x)==getW(f)?f:x); rotate(x); } upd(x); } void access(int x){ int y=0; while(x){ splay(x); ch[x][1] = y; upd(x); y = x; x = fa[x]; } } int findroot(int x){ access(x); splay(x); while(ch[x][0]) x = ch[x][0]; splay(x); return x; } void makeroot(int x){ access(x); splay(x); rev[x] ^= 1; } void split(int x, int y){ makeroot(x); access(y); splay(y); } void link(int x, int y){ makeroot(x); fa[x] = y; } void cut(int x, int y){ split(x, y); fa[x] = ch[y][0] = 0; } int main(){//anonymous Pro Regular cin>>n>>m>>q; for(int i=1; i<=m; i++){ scanf("%d %d %d", &edge[i].fro, &edge[i].too, &edge[i].val); if(edge[i].fro>edge[i].too) swap(edge[i].fro, edge[i].too); } sort(edge+1, edge+1+m, cmp); for(int i=1; i<=m; i++) mp[make_pair(edge[i].fro, edge[i].too)] = i; for(int i=1; i<=q; i++){ scanf("%d %d %d", &qu[i].opt, &qu[i].x, &qu[i].y); if(qu[i].x>qu[i].y) swap(qu[i].x, qu[i].y); if(qu[i].opt==2) vis[mp[make_pair(qu[i].x, qu[i].y)]] = true; } for(int i=n+1; i<=n+m; i++) val[i] = zdz[i] = i - n; int tmpcnt=0; for(int i=1; i<=m; i++){ if(tmpcnt==n-1) break; if(vis[i] || findroot(edge[i].fro)==findroot(edge[i].too)) continue; link(edge[i].fro, i+n); link(edge[i].too, i+n); tmpcnt++; } for(int i=q; i; i--){ if(qu[i].opt==1){ split(qu[i].x, qu[i].y); ans[i] = edge[zdz[qu[i].y]].val; } else{ split(qu[i].x, qu[i].y); int idx=mp[make_pair(qu[i].x, qu[i].y)]; int tmp=zdz[qu[i].y]; if(edge[idx].val<edge[tmp].val){ cut(edge[tmp].fro, tmp+n); cut(edge[tmp].too, tmp+n); link(edge[idx].fro, idx+n); link(edge[idx].too, idx+n); } } } for(int i=1; i<=q; i++) if(qu[i].opt==1) printf("%d\n", ans[i]); return 0; }

luogu4172 [WC2006]水管局長