zoukankan      html  css  js  c++  java
  • 无向图点双边双割边割点

    //割边
    int dfn[MAXN], low[MAXN], idx;
    bool bridge[MAXN];
    void tarjan(int now, int f)
    {
    	dfn[now] = low[now] = ++idx;
    	for (int i = head[now]; i; i = nxt[i])
    	{
    		if(v[i] == f) continue;
    		if(!dfn[v[i]])
    		{
    			tarjan(v[i], now);
    			low[now] = min(low[now], low[v[i]]);
    			if(low[v[i]] > dfn[now]) bridge[i] = bridge[i ^ 1] = 1;//成对变换,记录割边
    		}
    		else
    		{
    			low[now] = min(low[now], v[i]);
    		}
    	}
    }
    //割点 考虑根节点作为割点的情况
    int root, flag;//根,记录有几个根的子节点满足,要至少两个以上
    int dfn[MAXN], low[MAXN], idx;
    bool cut[MAXN];
    void tarjan(int now, int f)
    {
    	dfn[now] = low[now] = ++idx;
    	for (int i = head[now]; i; i = nxt[i])
    	{
    		if(v[i] == f) continue;
    		if(!dfn[v[i]])
    		{
    			tarjan(v[i], now);
    			low[now] = min(low[now], low[v[i]]);
    			if(low[v[i]] >= dfn[now]) 
    			{
    
    				if(now == root) flag++;
    				if(now != root || flag > 1) cut[now] = 1;
    			}
    		}
    		else
    		{
    			low[now] = min(low[now], v[i]);
    		}
    	}
    }
    //e-DCC 边双连通分量
    int e_dcc[MAXN], inddcc;
    int hdc[MAXN], vdc[MAXN], ndc[MAXN], cntdc = 1; 
    int c[MAXN];
    void adddc(int x, int y)
    {
    	ndc[++cntdc] = hdc[x]; hdc[x] = cntdc; vdc[cntdc] = y;
    }
    void dfs(int now)
    {
    	c[now] = inddcc; 
    	for (int i = head[now]; i; i = nxt[i])
    	{
    		if(c[v[i]] || bridge[i]) continue;
    		dfs(v[i]);
    	}
    }
    for (int i = 1; i <= n; i++)
    {
    	if(!c[i]) ++inddcc, dfs(i);
    }
    for (int i = 2; i <= tot; i++)
    {
    	int x = vdc[i], y = vdc[i ^ 1];
    	if(c[x] ^ c[y]) adddc(c[x], c[y]);
    }
    //v-DCC 点双连通分量
    vector<int> dcc[MAXN], inddcc;
    int hdc[MAXN], vdc[MAXN], ndc[MAXN], cntdc = 1;
    int root, flag;
    int dfn[MAXN], low[MAXN], idx;
    bool cut[MAXN];
    int stac[MAXN], top = 1;
    int c[MANX], new_id[MAXN], tot;
    void tarjan(int now, int f)
    {
    	dfn[now] = low[now] = ++idx;
    	stac[top++] = now;
    	if(now == root && head[now] == 0)
    	{
    		dcc[++inddcc].push_back(now);
    		return;
    	}
    	for (int i = head[now]; i; i = nxt[i])
    	{
    		if(v[i] == f) continue;
    		if(!dfn[v[i]])
    		{
    			tarjan(v[i], now);
    			low[now] = min(low[now], low[v[i]]);
    			if(low[v[i]] >= dfn[now]) 
    			{
    				if(now == root) flag++;
    				if(now != root || flag > 1) cut[now] = 1;
    				++inddcc;
    				while(stac[top - 1] != v[i])
    				{
    					dcc[inddcc].push_back(stac[--top]); 
    				}
    				dcc[inddcc].push_back(now);
    			}
    		}
    		else
    		{
    			low[now] = min(low[now], v[i]);
    		}
    	}
    }
    void adddc(int x, int y)
    {
    	ndc[++cntdc] = hdc[x]; hdc[x] = cntdc; vdc[cntdc] = y;
    }
    tot = inddcc;
    for (int i = 1; i <= n; i++)
    {
    	if(cut[i]) new_id[i] = ++tot;
    }
    for (int i = 1; i <= inddcc; i++)
    	for (int j = 0; j < dcc[i].size(); j++)
    	{
    		if(cut[dcc[i][j]]) 
    		{
    			adddc(i, new_id[dcc[i][j]]);
    			adddc(new_id[dcc[i][j]], i);
    		}
    		else c[d[i][j]] = i;
    	}
    
  • 相关阅读:
    haoop 断电后导致block文件损坏
    笔记本上小固态硬盘的使用
    centos 7安装部署docker
    用msbuild构建应用
    清风注解-Swift程序设计语言:Point11~15
    清风注解-Swift程序设计语言:Point6~10
    清风注解-Swift程序设计语言
    享骑电单车投诉
    yaf不输出致命错误(Fatal error)的原因(之一)
    如何面试 PHP 工程师?
  • 原文地址:https://www.cnblogs.com/hangzz/p/13299230.html
Copyright © 2011-2022 走看看