bzoj 3331 压力题解

这题目其实说实话还是很简单的,吗?

看到跟点有关系,其实就是求过程中的割点有多少个,这就直接用一个点双缩点,在缩点后,这个图就变成一个树了,而这里就直接用一个树上差分就可以解决。当然本身这个节点也是要记的。

(好吧,边双写了 20pts 的傻子也是在这里写题解了)。

#include<bits/stdc++.h>
#define pii pair<int,int>
using namespace std;
const int N=2E5+5;
int n,m,q,rt,id[N],low[N],st[N],dfn[N],cnt,top,dc,f[N][21],dep[N],cut[N],pre[N],res[N],px[N];
vector<pii>e[N];
vector<int>g[2*N],h[N];
void tarjan(int u,int ID) {
	low[u]=dfn[u]=++cnt;
	st[++top]=u;
	int f=0,y;
	for(auto tmp:e[u]) {
		int v=tmp.first,I=tmp.second;
		if(I==(ID^1))continue;
		if(!dfn[v]) {
			tarjan(v,I);
			low[u]=min(low[u],low[v]);
			if(low[v]>=dfn[u]) {
				f++,++dc;
				cut[u] =(f>1 || u!=1);
				do {
					y=st[top--],h[dc].push_back(y) ;
				} while(y!=v);
				h[dc].push_back(u);
			}
		} else low[u]=min(low[u],dfn[v]);
	}
}
void dfs(int rt,int fa){
	dep[rt]=dep[fa]+1;
	f[rt][0]=fa;
	for(int i=1;i<=20;i++)
		f[rt][i]=f[f[rt][i-1]][i-1];
	for(int p:g[rt]){
		if(p==fa)continue;
		dfs(p,rt);
	}
} 
void redfs(int rt,int fa){
	for(int p:g[rt]){
		if(p==fa)continue;
		redfs(p,rt);
		pre[rt]+=pre[p];
	}
} 
int LCA(int u,int v){
	if(dep[u]<dep[v])swap(u,v);
	int d=dep[u]-dep[v];
	for(int i=20;i>=0;i--)
		if(d&(1<<i))u=f[u][i];
	if(u==v)return u;
	for(int i=20;i>=0;i--)
		if(f[u][i]!=f[v][i])u=f[u][i],v=f[v][i];
	return f[u][0];
}
signed main() {
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1,x,y; i<=m; i++) {
		scanf("%d%d",&x,&y);
		e[x].push_back({y,2*i});
		e[y].push_back({x,2*i+1});
	}
	rt=1,tarjan(1,0);
	int num=dc;
	for(int i=1;i<=n;i++)if(cut[i])px[i]=++num;
	for(int i=1;i<=dc;i++)for(int j:h[i]){
		if(cut[j])g[i].push_back(px[j]),g[px[j]].push_back(i);
		else id[j]=i;
	}
	dfs(1,0);
	while(q--){
		int x,y;
		scanf("%d%d",&x,&y);
		if(!cut[x])res[x]++,x=id[x];
		else x=px[x];
		if(!cut[y])res[y]++,y=id[y];
		else y=px[y];
		int lca=LCA(x,y);
		++pre[x],++pre[y],--pre[lca],--pre[f[lca][0]];
	}
	redfs(1,0);
	for(int i=1;i<=n;i++){
		if(cut[i])cout<<pre[px[i]]<<endl;
		else cout<<res[i]<<endl;
	}
	return 0;
}
posted @ 2025-02-21 15:05  hnczy  阅读(22)  评论(0)    收藏  举报