• 关于有重边的强连通分量


    有向图的的情况比较简单只有一种强连通,重边和连向自己的边对于强连通都没有任何影响
    
    无向图的双连通要分点双连通(biconnected)和边双连通(edge_biconnected),连向自己的边对于俩种双连通也没有任何影响,但是重边对点双连通没有影响,但是对于边双连通有影响,因为在求边双连通时,要求对于任意俩点至少存在两条“边不重复”的路径,所以这个时候表示图我们不能用vector了,而是用邻接表,添加边的时候我们要一次添加正反俩条边,而且要相互可以索引查找,类似网络流里的反向弧,这样在我们dfs求割边时要以边的下标作为标记,在访问一了一条边时,要把这条边和其反向边同时标记为访问,最后对所有的边进行遍历,发现low[e.v] < pre[e.u]时,同样要把正反俩条边标记成割边,最后在不经过桥的情况下dfs求出边双连通分量即可
    struct EDGE
    {
    	int u, v;
    	int next;
    };
    
    int first[MAXN], rear;
    EDGE edge[MAXE];
    
    void init(int n)
    {
    	memset(first, -1, sizeof(first[0])*(n+1));
    	rear = 0;
    }
    
    void insert(int tu, int tv, int tw)
    {
    	edge[rear].u = tu;
    	edge[rear].v = tv;
    	edge[rear].next = first[tu];
    	first[tu] = rear++;
    	edge[rear].u = tv;
    	edge[rear].v = tu;
    	edge[rear].next = first[tv];
    	first[tv] = rear++;
    }
    
    struct FIND_BRIDGE
    {
    	int pre[MAXN], low[MAXN];
    	bool vis_e[MAXE];      //是否访问了边
    	bool is_bridge[MAXE];  //是否是桥
    	int dfs_clock;
    
    	void dfs(int cur)
    	{
    		pre[cur] = low[cur] = ++dfs_clock;
    		for(int i = first[cur]; ~i; i = edge[i].next)
    		{
    			int tv = edge[i].v;
    			if(!pre[tv])
    			{
    				vis_e[i] = vis_e[i^1] = true;
    				dfs(tv);
    				low[cur] = min(low[cur], low[tv]);
    				if(pre[cur] < low[tv]) is_bridge[i] = is_bridge[i^1] = true;
    			}
    			else
    				if(pre[tv] < pre[cur] && !vis_e[i])
    				{
    					vis_e[i] = vis_e[i^1] = true;
    					low[cur] = min(low[cur], pre[tv]);
    				}
    		}
    	}
    
    	void find_bridge(int n)
    	{
    		dfs_clock = 0;
    		memset(pre, 0, sizeof(pre[0])*(n+1));
    		memset(vis_e, 0, sizeof(vis_e[0])*rear);
    		memset(is_bridge, 0, sizeof(is_bridge[0])*rear);
    		for(int i = 1; i <= n; ++i)
    			if(!pre[i])
    				dfs(i);
    	}
    } fb;
    //接着在不经过桥的情况下dfs求出所有双强连通分量即可

  • 相关阅读:
    C#文件读写常用类介绍
    C#实现注销、重启和关机代码
    Mybatis学习---基础知识考核
    Linux操作系统各版本ISO镜像下载
    Java学习---JDK的安装和配置
    Java学习---基础知识学习
    Java学习---常见的模式
    Java实例---黑白五子棋[单机版]
    Java实例---简单的超市管理系统
    Java实例---简单的个人管理系统
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410697.html
Copyright © 2020-2023  润新知