无向图边双连通分量+构造双连通图

 

  边双连通分量: 边连通度大于1的连通分量

  在树中至少添加多少边能使得图变为边双连通图 ? 添加的边=(叶子节点+1)/2.

   在一个无向图中,我们可以把它的边双连通分量缩成一个点,然后一定会得到一颗树,然后按上述方法求叶节点即可。

  

  1 #include<cstdio>

  2 #include<cstring>

  3 #include<queue>

  4 #include<algorithm>

  5 #define _Clr(x, y) memset(x, y, sizeof(x))

  6 #define INF 0x3f3f3f3f

  7 #define N 5010

  8 using namespace std;

  9 

 10 struct Node

 11 {

 12     int to, next;

 13 }edge[N*2];

 14 int head[N], tot;

 15 int dfn[N], low[N];

 16 int bleg[N], Sta[N];

 17 bool instack[N];

 18 int n, cnt, ght, top;

 19 

 20 void Init()

 21 {

 22     cnt=tot=top=ght=0;

 23     _Clr(head, -1);

 24     _Clr(dfn, 0);

 25     _Clr(instack, 0);

 26 }

 27 

 28 void Add_edge(int a, int b)

 29 {

 30     edge[tot].to = b;

 31     edge[tot].next = head[a];

 32     head[a] = tot++;

 33 

 34     edge[tot].to = a;

 35     edge[tot].next = head[b];

 36     head[b] = tot++;

 37 }

 38 

 39 void dfs(int u, int f)

 40 {

 41     dfn[u]=low[u]=++cnt;

 42     instack[u] = true;

 43     Sta[top++] = u;

 44     for(int i=head[u]; i!=-1; i=edge[i].next)

 45     {

 46         int v = edge[i].to;

 47         if(i==(f^1)) continue;

 48         if(!dfn[v])

 49         {

 50             dfs(v, i);

 51             low[u] = min(low[u], low[v]);

 52         }

 53         else if(instack[v]) low[u] = min(low[u], dfn[v]);

 54     }

 55     if(low[u]==dfn[u])

 56     {

 57         ght++;

 58   //      printf("Num:%d\n", ght);

 59         while(1)

 60         {

 61             int v = Sta[--top];

 62             bleg[v] = ght;

 63  //           printf("%d ", v);

 64             instack[v] = false;

 65             if(u == v) break;

 66         }

 67    //     puts("");

 68     }

 69 }

 70 

 71 int de[N];

 72 void Tarjan()

 73 {

 74     int ans=0;

 75     dfs(1, -1);

 76     _Clr(de, 0);

 77     for(int u=1; u<=n; u++)

 78     for(int i=head[u]; i!=-1; i=edge[i].next)

 79     {

 80         int v = edge[i].to;

 81         if(bleg[v] != bleg[u]) de[bleg[v]]++;

 82     }

 83     for(int i=1; i<=ght; i++)

 84     {

 85     //    printf("de[%d]=%d \n", i, de[i]);

 86         if(de[i]==1) ans++;

 87     }

 88     printf("%d\n",(ans+1)>>1);

 89 }

 90 int main()

 91 {

 92     int m, a, b;

 93     while(~scanf("%d%d", &n, &m))

 94     {

 95         Init();

 96         while(m--)

 97         {

 98             scanf("%d%d", &a, &b);

 99             Add_edge(a, b);

100         }

101         Tarjan();

102     }

103     return 0;

104 }
View Code

 

你可能感兴趣的:(图)