zoukankan      html  css  js  c++  java
  • 学习笔记(双两通分量)

    双联通分量

    • 边双,对于任意两个点存在至少两条边不同的路径
    • 点双,对于任意两个点存在至少两条点不同的路径
    性质
    • 显然如果是点双就一定是边双
    求法
    • 边双有很好的求法,根据定义如果此边为割边(dfn[v]>low[u])(即u点儿子v无法到达u,此边为割边),那么一定不是边双,直接将割边去掉,剩下的联通快即为边双

    • 点双,同样运用到Tarjan算法,注意每次遍历一条边便将其压入栈中,如果该边为割点(low[v]>=dfn[u]),则像强连通那样一直弹边,将每条边的点标记,要注意,每个点都可能属于多个点双之中,每次覆盖成最新编号即可。一直弹到此边上一次出现即可

    • 此类问题写Tarjan时因为是双向边,所以要记一下父亲,不然要死循环在里面

    一道题改了一个晚上,效率低了点。说一下个人想法吧,最重要的是要注意如果没有被遍历过就Tarjan,否则还要判断如果他的儿子的dfs序在他之前却又不是他父亲,也要将这条边压入栈中。(看不懂那些压点的)
    板子 poj2942

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef int sign;
    typedef long long ll;
    #define For(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i)
    #define Fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i)
    const int N=1e3+5;
    bool cmax(sign &a,sign b){return (a<b)?a=b,1:0;}
    bool cmin(sign &a,sign b){return (a>b)?a=b,1:0;}
    template<typename T>T read()
    {
    	T ans=0,f=1;
    	char ch=getchar();
    	while(!isdigit(ch)&&ch!='-')ch=getchar();
    	if(ch=='-')f=-1,ch=getchar();
    	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-'0'),ch=getchar();
    	return ans*f;
    }
    void file()
    {
    	#ifndef ONLINE_JUDGE
    		freopen("2942.in","r",stdin);
    		freopen("2942.out","w",stdout);
    	#endif
    }
    int n,m;
    bool mp[N][N];
    int head[N],tt;
    int bl[N],cl[N],dfn[N],low[N],iscut[N],scc,id,dfs_clock;
    struct edge
    {
    	int u,v,nex;
    }e[N*N];
    int l[N],q[N];
    bool ok[N];
    void init()
    {
    	tt=0;dfs_clock=0;l[0]=q[0]=0;
    	memset(head,0,sizeof head);
    	memset(mp,0,sizeof mp);
    	memset(dfn,0,sizeof dfn);
    	memset(low,0,sizeof low);
    	memset(ok,0,sizeof ok);
    	memset(iscut,0,sizeof iscut);
    	memset(cl,0,sizeof cl);
    	memset(bl,0,sizeof bl);
    }
    void add(int x,int y)
    {
    	++tt;e[tt].u=x;e[tt].v=y;e[tt].nex=head[x];head[x]=tt;
    }
    void input()
    {
    	int x,y;
    	For(i,1,m)
    	{
    		x=read<int>();y=read<int>();
    		mp[x][y]=mp[y][x]=1;
    	}
    }
    void build()
    {
    	For(i,1,n)For(j,i+1,n)
    	{
    		if(!mp[i][j])add(i,j),add(j,i);
    	}
    }
    bool dfs(int u)
    {
    //	printf("%d
    ",u);
    	int v;
    	for(register int i=head[u];i;i=e[i].nex)
    	{
    		v=e[i].v;
    		if(bl[v]^id)continue;
    		if(cl[v]==cl[u])return 0;
    		if(!cl[v])
    		{
    			cl[v]=3-cl[u];
    			if(!dfs(v))return 0;
    		}
    	}
    	return 1;
    }
    void Tarjan(int u,int fa)
    {
    	int v,x,y,ch=0;
    	low[u]=dfn[u]=++dfs_clock;
    	for(register int i=head[u];i;i=e[i].nex)
    	{
    		v=e[i].v;
    		if(fa==v)continue;
    		if(!dfn[v])
    		{
    			l[++l[0]]=i;ch++;
    			Tarjan(v,u);
    			cmin(low[u],low[v]);
    			if(low[v]>=dfn[u])
    			{
    				iscut[u]=1;id++;
    				while(1)
    				{
    					x=e[l[l[0]]].u;y=e[l[l[0]--]].v;
    					//cerr<<x<<' '<<y<<endl;
    					if(bl[x]^id)bl[x]=id;
    					if(bl[y]^id)bl[y]=id;
    					if(x==u&&v==y)break;
    				}
    				cl[u]=1;
    				if(!dfs(u))
    				{
    					For(i,1,n)if(bl[i]==id)ok[i]=1;
    				}
    				cl[u]=0;q[0]=0;
    			}
    		}
    		else if(dfn[v]<dfn[u])
    		{
    			l[++l[0]]=i;//cerr<<1<<endl;
    			cmin(low[u],dfn[v]);
    		}
    	}
    	if(ch==1&&!fa)iscut[u]=0;
    }
    void work()
    {
    	For(i,1,n)
    	{
    		if(!dfn[i])Tarjan(i,0);
    	}
    	int cnt=0;
    	For(i,1,n)if(!ok[i])++cnt;
    	printf("%d
    ",cnt);
    }
    int main()
    {
    	file();
    	while(scanf("%d%d",&n,&m))
    	{
    		if(!n&&!m)break;
    		init();
    		input();
    		build();
    		work();
    	}
    	return 0;
    }
    
  • 相关阅读:
    【leetcode】Letter Combinations of a Phone Number
    【leetcode】_3sum_closest
    【leetcode】_3Sum
    【LeetCode】Longest Common Prefix
    入门:PHP:hello world!
    入门:HTML:hello world!
    入门:HTML表单与Java 后台交互(复选框提交)
    codeforces 712B. Memory and Trident
    codeforces 712A. Memory and Crow
    hdu 5878 I Count Two Three (2016 ACM/ICPC Asia Regional Qingdao Online 1001)
  • 原文地址:https://www.cnblogs.com/dengyixuan/p/8228394.html
Copyright © 2011-2022 走看看