深夜敲模板_4——无向图的割顶和桥

来源:互联网 发布:三国杀 游戏王 知乎 编辑:程序博客网 时间:2024/04/28 02:03
/***    dfs遍历一遍整个图,标出时间戳 dfs_clock,保存在pre[]里    遍历后得到一个森林    对于每一颗树,每个节点是割顶的情况:        1:根:    有两个或两个以上的子节点        2:非根:  对于节点u,low(u)表示u及u的所有节点的反向边所能连回的最早的节点的pre[]值                   如果u的所有子节点的low[v]>=pre[u]; 那么u节点就是割顶                   特别的,如果low[u]>pre[u],边(u,v)还是一个桥    初始化是,假设所有的low(u)=u;即所有节点都能连回自己***/1:int head[MAXN],pre[MAXN],low[MAXN],cnt,dfs_clock;bool iscut[MAXN],isedgecut[MAXM];///true表示是割顶struct Edge{    int v;    int next,to;}edge[MAXM>>1];void add(int u,int v){    edge[cnt].to = v;    edge[cnt].next = head[u];    head[u] = cnt++;}void init(){    cnt = dfs_clock = 0;    memset(head,-1,sizeof(head));    memset(pre,0,sizeof(pre));}void dfs(int u,int fa){    low[u] = pre[u] = ++dfs_clock;    int child = 0;    *****int lowv  = dfs_clock+1;    for(int i = head[u];i != -1;i = edge[i].next){        int v = edge[u].to;        if(!pre[v]){            child++;            dfs(v,u);            *****lowv = min(lowv,low[v]);            low[u] = min(low[u],low[v]);            if(low[v] >= pre[u])    iscut[u] = true;///这个地方也可以改成vector,找的时候更快            *****if(low[v] > pre[u])     isedgecut[i] = true;///找到的桥        }        else if(v != fa && pre[v] < pre[u]){            low[u] = min(low[u],pre[v]);        }    }    if(fa == -1 && child > 1)   iscut[u]=true;    *****if(fa == -1 && lowv != u){        for(int i = head[u];i != -1;i = edge[i].next)  isedgecut[i]=true;    }}2:vector <int> G[MAXN];*****vector < pair<int,int> > edge;void dfs(int u,int fa){    low[u] = pre[u] = ++dfs_clock;    int child = 0;    *****int lowv  = dfs_clock+1;    for(int i = 0;i < G[u].size();i++){        int v = G[u][v];        if(!pre[v]){            child++;            dfs(v,u);            *****lowv = min(lowv,low[v]);            low[u] = min(low[u],low[v]);            if(low[v] >= pre[u])    iscut[u] = true;            *****if(low[v] > pre[u])    edge.push_back(mak_pair(u,v));        }        else if(v != fa && pre[v] < pre[u]){            low[u] = min(low[u],pre[v]);        }    }    if(fa == -1 && child > 1)   iscut[u] = true;    *****if(fa == -1 && lowv != u){        for(int i = 0;i < G[u].size();i++)  edge.push_back(make_pair(u,v));    }}

0 0
原创粉丝点击