强连通分量——tarjan

struct ENode{ 
  int v,w,next; 
}edge[MAXM];  
int p[MAXN],ec;  
void InsertE(int u, int v, int w){ 
  edge[++ec].v = v; edge[ec].w = w; 
  edge[ec].next = p[u]; 
  p[u] = ec; 

int dfn[MAXN],cTime,low[MAXN]; //时间戳,时间戳计数,祖先时间。  
int gid[MAXN],gc; // 分量数组,分量计数。  
bool ins[MAXN]; stack<int> sTar;  //入栈标志,辅助栈  
void Tarjan(int u){ 
  dfn[u]=low[u]=++cTime;    //时间戳与祖先时间初始化  
  ins[u]=1; sTar.push(u); //入栈  
  for(int i=p[u];i;i=edge[i].next){  //递归处理所有子结点  
    int v=edge[i].v; 
    if(!dfn[v]){ 
      Tarjan(v); 
      low[u]=min(low[u],low[v]); //利用子孙,更新能回指的祖先时间戳  
    } 
    else if(ins[v])    //记录U能回指的最早祖先的时间戳  
      low[u]=min(low[u],dfn[v]); 
  } 
  if(low[u]>=dfn[u]){    //判断U是否分量的根  
    gc++; 
    int i; 
    do{ 
      i=sTar.top(); ins[i]=0; 
      gid[i]=gc; sTar.pop();  //分量出栈 
    }while(i!=u); //出栈至当前结点,包括当前结点  
  } 

猜你喜欢

转载自blog.csdn.net/to_more_excellent/article/details/81223918
今日推荐