1. 程式人生 > >LOJ121 動態圖連通(動態樹)

LOJ121 動態圖連通(動態樹)

mic freopen move poi ret bool graph getchar down

用LCT維護一下刪除時間的最大生成樹即可。當然也可以線段樹分治。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<0||c>9) {if (c==
-) f=-1;c=getchar();} while (c>=0&&c<=9) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 5010 #define M 500010 #define lson tree[k].ch[0] #define rson tree[k].ch[1] #define lself tree[tree[k].fa].ch[0] #define rself tree[tree[k].fa].ch[1] int n,m,x[N+M],y[N+M],v[N+M],cnt; map
<long long,int> f; struct edge{int op,x,y,del; }q[M]; struct data{int ch[2],fa,rev,s; }tree[N+M]; void up(int k) { tree[k].s=k; if (v[tree[lson].s]<v[k]) tree[k].s=tree[lson].s; if (v[tree[rson].s]<v[tree[k].s]) tree[k].s=tree[rson].s; } void rev(int k){if (k) swap(lson,rson),tree[k].rev^=1
;} void down(int k){if (tree[k].rev) rev(lson),rev(rson),tree[k].rev=0;} bool isroot(int k){return lself!=k&&rself!=k;} int whichson(int k){return rself==k;} void push(int k){if (!isroot(k)) push(tree[k].fa);down(k);} void move(int k) { int fa=tree[k].fa,gf=tree[fa].fa,p=whichson(k); if (!isroot(fa)) tree[gf].ch[whichson(fa)]=k;tree[k].fa=gf; tree[fa].ch[p]=tree[k].ch[!p],tree[tree[k].ch[!p]].fa=fa; tree[k].ch[!p]=fa,tree[fa].fa=k; up(fa),up(k); } void splay(int k) { push(k); while (!isroot(k)) { int fa=tree[k].fa; if (!isroot(fa)) if (whichson(fa)^whichson(k)) move(k); else move(fa); move(k); } } void access(int k){for (int t=0;k;t=k,k=tree[k].fa) splay(k),tree[k].ch[1]=t,up(k);} void makeroot(int k){access(k),splay(k),rev(k);} int findroot(int k){access(k),splay(k);for (;lson;k=lson) down(k);splay(k);return k;} void link(int x,int y){makeroot(x);tree[x].fa=y;} void cut(int x,int y){makeroot(x),access(y),splay(y);tree[y].ch[0]=tree[x].fa=0;up(y);} int query(int x,int y){makeroot(x),access(y),splay(y);return tree[y].s;} void newpoint(int p,int q,int z) { cnt++;tree[cnt].s=cnt;v[cnt]=z; x[cnt]=p,y[cnt]=q; link(cnt,p),link(cnt,q); } int main() { freopen("dynamic_graph.in","r",stdin); freopen("dynamic_graph.out","w",stdout); n=read(),m=read(); for (int i=1;i<=m;i++) { q[i].op=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].op==0) f[1ll*q[i].x*m+q[i].y]=i; if (q[i].op==1) q[f[1ll*q[i].x*m+q[i].y]].del=i; } cnt=n; for (int i=0;i<=n;i++) tree[i].s=i,v[i]=M; for (int i=1;i<=m;i++) if (q[i].op==0&&q[i].del==0) q[i].del=M; for (int i=1;i<=m;i++) if (q[i].op==0) { if (findroot(q[i].x)!=findroot(q[i].y)) newpoint(q[i].x,q[i].y,q[i].del); else { int t=query(q[i].x,q[i].y); if (v[t]<q[i].del) { cut(t,x[t]),cut(t,y[t]); newpoint(q[i].x,q[i].y,q[i].del); } } } else if (q[i].op==2) { if (findroot(q[i].x)!=findroot(q[i].y)||v[query(q[i].x,q[i].y)]<i) printf("N\n"); else printf("Y\n"); } fclose(stdin);fclose(stdout); return 0; }

LOJ121 動態圖連通(動態樹)