zoukankan      html  css  js  c++  java
  • 【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);
    	}
    }
    

     

  • 相关阅读:
    Common Element in Two Sorted Sets
    Nearest Points on a Plane
    Influencer Finder
    Range of Intervals
    *Common characters
    自定义栈 和装箱,拆箱
    1.Vector(同步)和ArrayList(异步)异同
    STL中的迭代器的使用
    如何优化limit?
    mysql五大引擎之间的区别和优劣之分
  • 原文地址:https://www.cnblogs.com/2018hzoicyf/p/11183386.html
Copyright © 2011-2022 走看看