Tarjan求图的连通性总结

来源:互联网 发布:java 请求webservice 编辑:程序博客网 时间:2024/05/19 10:37
有向图的Tarjan&缩点void tarjan(int x){ //Tarjan         int y = 0;          dfn[x]=low[x]=++dindex;          instack[x]=true;          stap[++stop]=x;          for (int i=0; i<e[x].size(); i++) {              y=e[x][i];              if (!dfn[y]) {                  tarjan(y);                  if (low[y]<low[x]) {                      low[x]=low[y];                  }              }              else if (instack[y]&&dfn[y]<low[x]){                  low[x]=dfn[y];              }          }          if (dfn[x]==low[x]) {              cnt++;              while (y!=x) {                  y=stap[stop--];                  instack[y]=false;                  belong[y]=cnt;              }          }      }  for (int i=1; i<=n; i++) {  //求强连通分量            if (!dfn[i]) {                  tarjan(i);              }          }  for (int i=1; i<=n; i++) {                  int size=e[i].size();                  for (int j=0; j<size; j++) {                      if (belong[i]!=belong[e[i][j]]) {                          outdeg[belong[i]]++;                          indeg[belong[e[i][j]]]++;                      }                  }              }              int sumout=0,sumin=0;              for (int i=1; i<=cnt; i++) {                  if (outdeg[i]==0) {                      sumout++;                  }                  if (indeg[i]==0) {                      sumin++;                  }              }  
无向图的Tarjanvoid tarjan_addedge(int u,int father)//Tarjan求无向图的割边{    int i,v;    low[u]=dfn[u]=index++;    for(i=head[u];i!=-1;i=edge[i].next)    {        v=edge[i].to;        if(v==father)continue;        if(dfn[v]==-1)        {            tarjan(v,u);            low[u]=low[u]>low[v]?low[v]:low[u];            if(low[v]>dfn[u])//桥            {                bridge[cnt++]=i;            }        }        else low[u]=low[u]>dfn[v]?dfn[v]:low[u];    }}来自 <http://acm.hust.edu.cn/vjudge/contest/source/6487492> void Tarjan_Point(int x)//Tarjan求无向图的割点{    id++;    low[x] = dfn[x] = id;    vis[x] = 1;    for(int i = head[x]; i!=-1; i=edge[i].next)    {        int y=edge[i].v;        if(!vis[y])        {            Tarjan(y);            low[x] = min(low[x],low[y]);            if(low[y] >= dfn[x] && x != 1)            {                num1[x]++;            }            else if(x == 1)                numson++;        }        else            low[x] = min(low[x],dfn[y]);    }}来自 <http://acm.hust.edu.cn/vjudge/contest/source/6501942> if (low[v] != low[i])//无向图判断是不是一个双连通分量{    cnt[low[i]] ++;}来自 <http://acm.hust.edu.cn/vjudge/contest/source/6491720> 
0 0
原创粉丝点击