tarjan求强连通分量是否可以不开low数组?
  • 板块学术版
  • 楼主elsc
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/3/4 21:25
  • 上次更新2024/3/5 12:37:39
查看原帖
tarjan求强连通分量是否可以不开low数组?
750618
elsc楼主2024/3/4 21:25

tarjan算法大概长这样(来自某大佬的题解):

void tarjan(int x){  
    sta[++top]=x;
    pd[x]=1;
    DFN[x]=LOW[x]= ++Index;
    for(int i=fir[x];i;i=Next[i]){
        int v=to[i];
        if(!DFN[v]){
            tarjan(v);
            LOW[x]=min(LOW[x],LOW[v]);
        }
        else if(pd[v]){
            LOW[x]=min(LOW[x],DFN[v]);
        }
    }
    if(DFN[x]==LOW[x]){
        tot++;
        while(sta[top+1]!=x){
            color[sta[top]]=tot;
            sum[tot]+=val[sta[top]];
            pd[sta[top--]]=0;
        }
    }
}

那是否可以不开low数组,用返回值代替,像这样?

struct Stack {
   int t = 0;
   int a[10005];
   bool f[10005];
   inline void push(int x) {a[++t] = x; f[x] = true;}
   inline int pop() {int x = a[t--]; f[x] = false; return x;}
   inline bool in(int v) {return f[v];}
};
Stack s;
int dfn[10005];
int timed = 0, cnt = 0;
int scc[10005];
int tarjan(int u) {
   s.push(u);
   int low = dfn[u] = ++timed;
   for (int i = head[u]; i != -1; i = E[i].next) {
   	int v = E[i].to;
   	if (dfn[v] == 0) {
   		low = std::min(low, tarjan(v));
   	} else if (s.in(v)) {
   		low = std::min(low, dfn[v]);
   	}
   }
   if (dfn[u] == low) {
   	++cnt;
   	do scc[s.pop()] = cnt;
   	while (s.in(u));
   }
   return low;
}

试了试,应该是可行的(code),但我还是有点疑惑:

  1. 是否可以证明其正确性?
  2. 如果是正确的,为什么习惯的写法中会加low数组?

望大佬解答qwq。

2024/3/4 21:25
加载中...