无向图的顶点连通度

  

无向图的顶点连通度需要用到网络流来求,并且有以下定理;

Mengerg定理: 无向图的顶点连通度K和顶点间的最大独立轨数目之间存在如下关系:

① 当图为完全图时: k=V-1  (V表示图中顶点数)

② 当图为非完全图h时: K=min{ P(A, B) | 任意不相邻的顶点AB }

注意:如果AB相邻的话,那么删除图中所有其他的点后,AB任然连通,故强调不相邻。

 

独立轨:设A,B是无向图G的两个顶点,从A到B的两条没有公共顶点的路径,互称为独立轨。

最大独立轨数:A到B独立轨的最大条数,记作P(A,B)。

 

现在,求无向图G的顶点连通度就相当于求G中任意两点间u最大独立轨数(P(A,B))的最小值。

求P(A,B)的方法如下:

(1) 构造一个容量网络。

  ① 原图G中每个顶点v拆分为两个点v1  v2 ,并且v1  v2 之间连一条容量为1的单向弧。

  ② 原图G中每条变e=(u,v)在容量网络中有两条弧e1 =(u1 , v2 ),e2  =(u2 , v1 ),容量均为INF。

  ③ 另设A2 为源点,B1 为汇点。

(2)求从A2 到B1 的最大流F。

(3)流处源点的流量之和就是P(A,B),所有具有流量1的弧<v,v>对应的顶点v构成一个割顶集,删除这个割顶集,A,B之间不在连通。

 

所以,根据以上定理,得出求无向图G的顶点连通度的思路:

(1) 设K的初始值为INF。

(2) 分析图中每对不相邻的顶点AB,求出P(A,B)和割顶集。

(3)  K=min (K, P(A,B)),保存割顶集。

(4) 重复(2)(3),直到图中所有不相邻顶点分析完为止。

 

 

给出POJ1966代码:

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define _Clr(x, y) memset(x, y, sizeof(x))
#define INF 0x3f3f3f3f
#define N 300
using namespace std;

int map[N][N], flow[N][N];
int que[N], n, St[N];
int alpha[N], pre[N];

// 求S到T的最大流
int MaxFlow(int S, int T)
{
    int maxf=0, m=2*n;
    _Clr(flow, 0);
    queue<int> Q;
    while(1)
    {
        _Clr(pre, -1);
        _Clr(alpha, 0);
        pre[S] = S;
        alpha[S] = INF;
        Q.push(S);
        while(!Q.empty())
        {
            int u = Q.front(); Q.pop();
            for(int i=0; i<m;  i++)
            {
                if(pre[i]==-1 && flow[u][i]<map[u][i])
                {
                    pre[i] = u;
                    alpha[i] = min(alpha[u], (map[u][i]-flow[u][i]));
                    Q.push(i);
                }
            }
        }
        if(alpha[T] == 0) break;
        
        maxf += alpha[T];
        for(int i=T; i!=S; i=pre[i])
        {
            flow[pre[i]][i] += alpha[T];
            flow[i][pre[i]] -= alpha[T];
        }
    }
    return maxf;
}

void BuildMap(int m)
{
    int a, b;
    _Clr(map, 0);
    for(int i=0; i<n; ++i) map[i][i+n] = 1;
    while(m--)
    {
        scanf(" (%d,%d)", &a, &b);
        map[a+n][b] = map[b+n][a] = INF;
    }
}

int main()
{
    int m;
    while(~scanf("%d%d", &n, &m))
    {
        BuildMap(m);
        int ans=INF;
        for(int i=1; i<n; i++)
            ans = min(ans, MaxFlow(n, i));
        printf("%d\n", ans==INF?n:ans);
    }
    return 0;
}
View Code

 

posted @ 2015-03-25 18:31  无道圣君  阅读(1933)  评论(0编辑  收藏  举报