code

#include<bits/stdc++.h>
//#define feyn
const int N=300010,M=600010,R=100;
using namespace std;
inline void read(int &wh){
	wh=0;char w=getchar();int f=1;
	while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
	while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
	wh*=f;return;
}
inline int min(int s1,int s2){return s1<s2?s1:s2;}
inline void swap(int &s1,int &s2){int s3=s1;s1=s2;s2=s3;return;}

int m,n,q,num,s,t,c[N],siz[N],color;
namespace P3{
	int st[R],top,rs[R],tot;
	struct edge{int t,v,nxt;}e[R];int head[N],esum;
	inline void adde(int fr,int to,int val){e[++esum]=(edge){to,val,head[fr]};head[fr]=esum;st[++top]=rs[++tot]=fr;}
	inline void add(int fr,int to,int val){adde(fr,to,val);adde(to,fr,val);}
	int tx[N],ty[N],nt;
	inline void dfs(int wh,int vis[],bool op){
		vis[wh]=nt;
		for(int i=head[wh],th;i;i=e[i].nxt){if((i&1)!=op||vis[th=e[i].t]==nt)continue;dfs(th,vis,op);}
	}
	void main(){
		nt++;dfs(s,tx,1);dfs(t,ty,0);int ans=0;
		sort(rs+1,rs+tot+1);tot=unique(rs+1,rs+tot+1)-rs-1;
		for(int i=1;i<=tot;i++){
			int x=rs[i];ans+=(tx[x]==nt&&ty[x]==nt)*siz[x];
			for(int j=head[x],th;j;j=e[j].nxt)
				if(tx[x]==nt&&ty[th=e[j].t]==nt&&(j&1))ans+=e[j].v;
		}
		printf("%d\n",ans);while(top)head[st[top--]]=0;tot=esum=0;
	}
}
namespace P2{
	struct edge{int t,nxt;}e[M];int head[N],esum,d[N];
	inline void add(int fr,int to){e[++esum]=(edge){to,head[fr]};d[to]++;head[fr]=esum;}
	int root,qq[N],ll=1,rr,fa[N],dfn[N],cnt,son[N],sizz[N],top[N],dep[N],sumData[N];
	inline void dfs(int wh){
		dfn[wh]=++cnt;sizz[wh]=1;sumData[wh]+=siz[wh];
		for(int i=head[wh],th;i;i=e[i].nxt){
			dep[th=e[i].t]=dep[wh]+1;sumData[th]=sumData[wh];
			dfs(th);sizz[wh]+=sizz[th];
			sizz[th]>sizz[son[wh]]&&(son[wh]=th);
		}
	}
	inline void find(int wh,int ntop){
		top[wh]=ntop;if(son[wh])find(son[wh],ntop);
		for(int i=head[wh],th;i;i=e[i].nxt)if((th=e[i].t)^son[wh])find(th,th);
	}
	inline int lca(int x,int y){
		while(top[x]^top[y]){if(dep[top[x]]<dep[top[y]])swap(x,y);x=fa[top[x]];}
		return dep[x]<dep[y]?x:y;
	}
	inline bool cmp(int s1,int s2){return dfn[s1]<dfn[s2];}
	void solve(){
		int aa,bb,cc[R]={0},tot=0;read(s);read(t);s=c[s],t=c[t];cc[++tot]=s;cc[++tot]=t;
		for(int i=1;i<=num;i++){
			read(aa);read(bb);aa=c[aa],bb=c[bb];if(aa==bb)continue;
			P3::add(aa,bb,0);cc[++tot]=aa;cc[++tot]=bb;
		}
		sort(cc+1,cc+tot+1,cmp);tot=unique(cc+1,cc+tot+1)-cc-1;
		int sta[R]={0},nowTop=0;if(cc[1]^root)sta[++nowTop]=root;
		for(int i=1;i<=tot;i++){
			int wh=cc[i],lc=lca(wh,sta[nowTop]);
			while(nowTop>1)
				if(dep[lc]<dep[sta[nowTop-1]]){
					int x=sta[nowTop-1],y=sta[nowTop];nowTop--;P3::add(x,y,sumData[fa[y]]-sumData[x]);}
				else{if(dep[lc]<dep[sta[nowTop]]){
						int x=sta[nowTop];nowTop--;P3::add(lc,x,sumData[fa[x]]-sumData[lc]);}break;}
			if(lc^sta[nowTop])sta[++nowTop]=lc;
			if(wh^sta[nowTop])sta[++nowTop]=wh;
		}
		while(nowTop>1){
			int x=sta[nowTop-1],y=sta[nowTop];nowTop--;
			P3::add(x,y,sumData[fa[y]]-sumData[x]);
		}P3::main();return;
	}
	void main(){
		for(int i=1;i<=color;i++)if(d[i]==0)qq[++rr]=i,root=i;
		while(ll<=rr){
			int wh=qq[ll++];
			for(int i=head[wh],th;i;i=e[i].nxt)d[th=e[i].t]--,d[th]==0&&(qq[++rr]=th,fa[th]=wh);
		}
		esum=0;memset(head,0,sizeof(head));
		for(int i=1;i<=color;i++)if(fa[i])add(fa[i],i);
		dfs(root);find(root,root);while(q--)solve();
	}
}
namespace P1{
	struct edge{int t,nxt;}e[M];
	int head[N],esum;
	inline void add(int fr,int to){e[++esum]=(edge){to,head[fr]};head[fr]=esum;}
	int cnt,dfn[N],low[N],st[N],top;
	inline void dfs(int wh){
		dfn[wh]=low[wh]=++cnt;st[++top]=wh;
		for(int i=head[wh],th;i;i=e[i].nxt){
			if(dfn[th=e[i].t]==0)dfs(th),low[wh]=min(low[wh],low[th]);
			else if(c[th]==0)low[wh]=min(low[wh],dfn[th]);
		}
		if(dfn[wh]^low[wh])return;color++;int x;
		do c[x=st[top--]]=color,siz[color]++;while(x^wh);
	}
	void main(){
		read(m);read(n);read(q);read(num);int s1,s2;
		for(int i=1;i<=n;i++){read(s1);read(s2);add(s1,s2);}
		for(int i=1;i<=m;i++)if(dfn[i]==0)dfs(i);
		for(int x=1;x<=m;x++)
			for(int i=head[x],y;i;i=e[i].nxt)
				if(c[x]^c[y=e[i].t])P2::add(c[x],c[y]);
	}
}

signed main(){
	
	#ifdef feyn
	freopen("in.txt","r",stdin);
	#endif
	
	P1::main();P2::main();
	
	return 0;
}
posted @ 2022-10-18 17:34  Feyn618  阅读(39)  评论(0编辑  收藏  举报