【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\n",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\n",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);
}
}