连通分量相关代码

// 割边
void tar(int x,int in_e)
{
  dfn[x] = low[x] = ++cnt;
  for(int i=hd[0][x],y=vr[i]; i; i=nt[i],y=vr[i])
    if(!dfn[y])
    {
      tar(y,i);
      low[x] = min(low[x],low[y]);
      
      if(low[y]>dfn[x]) bri[i]=bri[i^1]=true;
    } else
        if(i != (in_e^1)) low[x]=min(low[x],dfn[y]);
}

//割点
void tar(int x)
{
  dfn[x] = low[x] = ++cnt;
  if(rt==x && !hd[x])
  {
    dcc[++dcnt].clear();
    dcc[dcnt].push_back(x);
    return;
  }
  sta[++tp] = x;
  for(int i=hd[x],y=vr[i]; i; i=nt[i],y=vr[i])
    if(!dfn[y])
    {
      tar(y);
      low[x] = min(low[x],low[y]);
      
      if(low[y]>=dfn[x])
      {
        ++flg;
        if(flg>1 || x!=rt) cut[x]=true;

        dcc[++dcnt].clear();
        int z;
        do{
          z=sta[tp--];
          dcc[dcnt].push_back(z);
        } while(z!=y);
        dcc[dcnt].push_back(x);
      }
    }
    else low[x] = min(low[x],dfn[y]);
}

//tarjan 强连通分量
void tar(int x) {
	low[x] = dfn[x] = ++dcnt;
	s[++tp] = x, in_stack[x] = true;
	for(int i=hd[x]; i; i=nt[i]) {
		int y = vr[i];
		if(!dfn[y]) {
			tar(y);
			low[x] = min(low[x], low[y]);
		} else if(in_stack[y]) {
			low[x] = min(low[x], dfn[y]);
		}
	}
	if(dfn[x] == low[x]) {
		++scnt;
		while(s[tp] != x) {
			scc[s[tp]] = scnt;
			++siz[scnt];
			in_stack[s[tp]] = false;
			--tp;
		}
		scc[s[tp]] = scnt;
		++siz[scnt];
		in_stack[s[tp]] = false;
		--tp;
	}
}
posted @ 2021-01-03 09:03  xwmwr  阅读(114)  评论(0编辑  收藏  举报