【BZOJ3331】[BeiJing2013]压力 v-DCC缩点的板子

分析:

  不多解释,

   v-DCC缩点的板子+树上差分+LCA

 

   v-DCC的板子得好好学啊! 

  

受益匪浅的图(来自zkt)

有虚点,注意范围

#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
#define MAXN 200010
using namespace std;
inline int minn(int a,int b){
	return a<b?a:b;
}
inline int read(){
	int s=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar(); }
	while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
	return s*w;
}
int T,n,m;
struct rr{
	int nt,to;
}bl[MAXN*4];int hd[MAXN*2],itot;
void add(int x,int y){
	bl[++itot].to=y;
	bl[itot].nt=hd[x];
	hd[x]=itot;
}
int dfn[MAXN],low[MAXN],num;
int stack[MAXN],top;
vector<vector<int> >dcc(MAXN);int tot;
bool cut[MAXN];
void tarjan(int u,int fa){
	dfn[u]=low[u]=++num;
	stack[++top]=u;
	int tto,flag=0;
	for(int i=hd[u];i;i=bl[i].nt){
		tto=bl[i].to;
		if(tto==fa)continue;
		if(!dfn[tto]){
			tarjan(tto,u);
			low[u]=minn(low[u],low[tto]);
			if(low[tto]>=dfn[u]){
				++flag;
				if(u!=1||flag>=2)
					cut[u]=1;
				++tot;
				int tan=stack[top];
				while(tan!=tto){
					dcc[tot].push_back(tan);
					tan=stack[--top];
				}
				--top;
				dcc[tot].push_back(tan);
				dcc[tot].push_back(u);
			}
		}
		else low[u]=minn(low[u],dfn[tto]);
	}
}
int belong[MAXN];
int ys[MAXN*2];
void init(){
/*	for(int i=1;i<=tot;++i){
		cout<<i<<endl;
		for(int k=0;k<dcc[i].size();++k){
			cout<<dcc[i][k]<<" ";
		}
		cout<<endl;
	}*/
	int lin=tot;//防止tot超,爆dcc的vector
	for(int i=1;i<=n;++i)
		if(cut[i]){
			belong[i]=++lin;
			ys[lin]=i;
		}
	int y;
	memset(hd,0,sizeof(hd));
	itot=0;
	for(int i=1;i<=tot;++i)
		if(dcc[i].size())
			for(int k=0;k<dcc[i].size();++k)
				if(cut[y=dcc[i][k]]){
					add(belong[y],i);
					add(i,belong[y]);
				}
				else belong[y]=i;
/*	cout<<belong[2]<<" "<<belong[3]<<endl;
	for(int i=1;i<=tot;++i){
		cout<<"QwQ"<<i<<endl;
		for(int k=0;k<e[i].size();++k)
			cout<<e[i][k]<<" ";
		cout<<endl;
	}*/
}
vector<int >dan;
vector<int >zz;
bool ok;
void dfs(int u,int fa){
//	printf("qwq u=%d fa=%d
",u,fa);
	if(ok)return ;
	if(u==belong[n]){
		ok=1;
		for(int k=0;k<dan.size();++k)
			if(ys[dan[k]]&&ys[dan[k]]!=1)
				zz.push_back(ys[dan[k]]);
		sort(zz.begin(),zz.end());
		printf("%d
",zz.size());
		for(int k=0;k<zz.size();++k)
			printf("%d ",zz[k]);
		puts("");
		return ;
	}
	int tto;
	dan.push_back(u);
	for(int i=hd[u];i;i=bl[i].nt){
		tto=bl[i].to;
		if(tto==fa)continue;
		dfs(tto,u);
	}
	dan.pop_back();
	return ;
}
void shan(){
	itot=top=num=0;
	memset(hd,0,sizeof(hd));
	memset(dfn,0,sizeof(dfn));
	memset(belong,0,sizeof(belong));
	memset(ys,0,sizeof(ys));
	memset(cut,0,sizeof(cut));
	for(int i=1;i<=tot;++i){
		dcc[i].clear();
	}
	tot=0;
}
int main(){
//	freopen("da.in","r",stdin);
	T=read();
	while(T){
		--T;
		shan();
		n=read();m=read();
		for(int i=1,a,b;i<=m;++i){
			a=read();b=read();
			add(a,b);add(b,a);
		}
		tarjan(1,0);
		init();
		ok=0;
		dan.clear();
		zz.clear();
		dfs(belong[1],0);
	}
}

 

原文地址:https://www.cnblogs.com/2018hzoicyf/p/11183386.html