连通图

来源:互联网 发布:java基础教学视频 编辑:程序博客网 时间:2024/05/09 11:30

强连通

void tarjan(int u){      dfn[u] = low[u] = ++tim;      vis[u] = 1;      sta.push(u);      for(int i = head[u]; ~i; i = edge[i].next){          int& v = edge[i].to;          if(!dfn[v]){              tarjan(v);          }          if(vis[v]==1){              low[u] = min(low[u],low[v]);          }      }      if(dfn[u] == low[u]){          while(!sta.empty()){              int v = sta.top();              sta.pop();              vis[v] = 2;              ans[num] += val[v];              pos[v] = num;              if(u==v)break;          }          ++num;      }  } 

求有多少割点?

//cnt 为割点的个数//root 为根//ans 为删除该割点后连通图个数.//若割点为root,则输出ans[root],否则,输出ans[]+1;void tarjan(int u,int pre){    dfn[u] = low[u] = ++tim;    int k = 0;    for(int i = head[u]; ~i; i = edge[i].next)    {        const int& v = edge[i].to;        if(v == pre) continue;        if(!dfn[v])        {            ++k;            tarjan(v,u);            low[u] = min(low[u],low[v]);            if(u == root && k > 1){                flag[u] = 1;                ans[u] = k;            }            if(u != root && low[v] >= dfn[u]){                flag[u] = 1;                ans[u]++;            }        }        else low[u] = min(low[u],dfn[v]);    }    cnt += flag[u];}

求边连通分量

pos代表属于哪一个边连通分量

bridge代表桥

void tarjan(int u,int fa){    dfn[u] = low[u] = ++tim;    sta[tp++] = u;    for(int i = head[u];~i;i=edge[i].next){        int v = edge[i].to;        if(v == fa)continue;        if(!dfn[v]){            tarjan(v,u);            low[u] = min(low[u],low[v]);            if(low[v] > dfn[u]){                bridge[++bridgeNum]={u,v};            }        }        else if(dfn[v] < dfn[u]){            low[u] = min(low[u],dfn[v]);        }    }    if(dfn[u] == low[u]){        ++num;        int v;        do{            v = sta[--tp];            pos[v] = num;        }while(v != u);    }}

点双连通分量

void tarjan(int u,int father){      dfn[u] = low[u] = ++time;      for(int i=head[u]; ~i; i=edge[i].next){          int v = edge[i].to;          if(!dfn[v]){              sta.push(u);//存点              tarjan(v,u);              low[u] = min(low[u],low[v]);              if(low[v] >= dfn[u]){                  ++num;                  while(!sta.empty()){                      int j = sta.top();                      sta.pop();                      vec[num].push_back(j);//存的点                      if(j == u)break;                  }            }        }        else if(dfn[v] < dfn[u]){              sta.push(u);              low[u] = min(low[u],dfn[v]);          }    }}











0 0