无向图点双边双割边割点

//割边
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;
	}
posted @ 2020-07-14 15:15  行zzz  阅读(137)  评论(0编辑  收藏  举报