现在,我想知道自己是否还有选择。
给定n个点m条边的无向图以及顺序发生的q个事件。
每个事件都属于下面两种之一:
1、删除某一条图上仍存在的边
2、询问是否存在两条边不相交的路径可以从点u出发到点v
标签:
#include<cstdio> #include<algorithm> const int N=100010,M=10000000; char buf[M+2],*ptr=buf-1; inline int _int(){ int x=0,c=*++ptr; while(c>57||c<48)c=*++ptr; while(c>47&&c<58)x=x*10+c-48,c=*++ptr; return x; } inline int getop(){ int c=*++ptr; while(c<‘A‘||c>‘Z‘)c=*++ptr; return c; } struct edge{int a,b;}e[100010]; bool operator<(edge a,edge b){ return a.a!=b.a?a.a<b.a:a.b<b.b; } int n,m,q; int qs[N][3]; bool ans[N]; int del[N]; int es[N*2],enx[N*2],e0[N],ep=2,f[N],F[N],F1[N],dep[N],fa[N]; int ed[N*2]; int dfn[N],low[N],T=0; int get(int x){ int a=x,c; while(x!=f[x])x=f[x]; while(x!=(c=f[a]))f[a]=x,a=c; return x; } int Get(int x){ int a=x,c; while(x!=F[x])x=F[x]; while(x!=(c=F[a]))F[a]=x,a=c; return x; } void swap(int&a,int&b){int c=a;a=b;b=c;} void tj(int w){ dfn[w]=low[w]=++T; for(int i=e0[w];i;i=enx[i]){ int u=es[i]; if(ed[i]){ if(ed[i]==2&&!dfn[u]){ dep[u]=dep[w]+1; fa[u]=w; tj(u); } continue; } if(!dfn[u]){ ed[i^1]=1; dep[u]=dep[w]+1; fa[u]=w; tj(u); if(low[u]<low[w])low[w]=low[u]; if(low[u]<=dfn[w])f[get(u)]=get(w); }else if(dfn[u]<low[w])low[w]=dfn[u]; } } int main(){ fread(buf,1,M,stdin); n=_int();m=_int();q=_int(); for(int i=0;i<m;i++){ int a=_int(),b=_int(); if(a>b){int c=a;a=b;b=c;} e[i]=(edge){a,b}; } std::sort(e,e+m); for(int i=1;i<=q;i++){ qs[i][0]=(getop()==‘Z‘); int a=qs[i][1]=_int(); int b=qs[i][2]=_int(); if(qs[i][0]){ if(a>b)swap(a,b); edge w=(edge){a,b}; ++del[std::lower_bound(e,e+m,w)-e]; } } for(int i=1;i<=n;i++)F[i]=f[i]=i; for(int i=0;i<m;i++){ if(del[i]>1)for(int j=0,c=del[i];j<c;j++)del[i+j]=1; if(del[i])continue; int a=e[i].a,b=e[i].b; es[ep]=b;enx[ep]=e0[a];e0[a]=ep++; es[ep]=a;enx[ep]=e0[b];e0[b]=ep++; F[Get(a)]=Get(b); } for(int i=1;i<=n;i++)F1[i]=F[i]; for(int i=q;i;i--)if(qs[i][0]){ int a=qs[i][1],b=qs[i][2]; if(Get(a)==Get(b))continue; ed[ep]=2;es[ep]=b;enx[ep]=e0[a];e0[a]=ep++; ed[ep]=2;es[ep]=a;enx[ep]=e0[b];e0[b]=ep++; F[Get(a)]=Get(b); } for(int i=1;i<=n;i++)if(!dfn[i])tj(i); for(int i=1;i<=n;i++)F[i]=F1[i]; for(int i=q;i;i--){ int a=qs[i][1],b=qs[i][2]; if(qs[i][0]){ if(Get(a)!=Get(b)){ if(dep[a]<dep[b])swap(a,b); fa[a]=b; F[Get(a)]=Get(b); continue; } a=get(a);b=get(b); while(a!=b){ if(dep[a]<dep[b])swap(a,b); f[a]=get(fa[a]); a=fa[a]; } }else ans[i]=(get(a)==get(b)); } for(int i=1;i<=q;i++)if(!qs[i][0])puts(ans[i]?"Yes":"No"); return 0; }
标签:
原文地址:http://www.cnblogs.com/ccz181078/p/5628022.html