无向图的最大割问题的实现

来源:互联网 发布:淘宝店铺平价女包 编辑:程序博客网 时间:2024/05/01 22:28

问题描述:

什么是无向图的最大割?

有无向图G=(V,E).设U是V的一个子集。对任意的顶点u,v如果(u,v)是E中的一条边,如果u在U中,则v一定不

在U中,这样的边称为顶点集合U的一个割边。那个这个顶点集合U所有的割边就构成图G的一个割。最大割

的意思,就是说含割边最多的割。

编程任务:

给定一个无向图G,计算G的最大割。

数据输入:

第一行2个整数 n,e表示顶点个数和边个数。下面e行是边,每行2个整数对应顶点编号。顶点编号从1-n;

数据输出:

第一行是最大割的边数。

第二行是顶点集的向量对应1-n,0表示不在集合,1表示在集合。

解题思想:

这道题也是一个子集选取问题,所以它的解空间树是一个子集树。这个集合n个元素,每个元素可以有

选取或不选取2种选择,所以共用2^n个子集。

这里用分支界限法。

分支界限法:类似宽度优先搜索,它和回溯的区别在与,它每次都取一个节点,然后把它的所有的儿子节点

都扩展,然后加到队列中,所以说,分支界限法,这种扩展方式导致没个节点最多一次扩展机会,它在扩展

它的分支的时候,根据一定的界限条件,或淘汰不可能产生最优解的分支。

这里的队列有2种,一种是普通队列就是先进先出。

另一种就是优先级队列,它会根据优先级进行出队,这和Windows中的消息队列类似。

在C++中,STL中priority_queue就是优先级队列。queue是普通队列。优先级队列可以用最大堆或最小堆

实现。

#include <iostream>
#include <queue>
using namespace std;

int n,e;//顶点数和边数
int Graph[200][200];//存储图的邻接矩阵
int bestcut = 0;//存储最优解
int bestx[200];//存储最优解
struct HeapNode//队列节点
{
HeapNode()
{
      memset(x,0,sizeof(x));
}
int i;
int cut;
int edges;
int x[200];
    booloperator < (const HeapNode&a)const
{
   returncut<a.cut;
}
};
void maxcut()
{
    HeapNodeE;
priority_queue<HeapNode> Q;
E.cut = 0;
E.edges = e;
E.i = 0;
while (1)
{
   if (E.i==n)
   {
           if (E.cut>bestcut)
           {
    bestcut = E.cut;
    memcpy(bestx,E.x,sizeof(int)*n);
           }
   }
   else
   {
    HeapNodetemp = E;
    int i =E.i;
    for (intj=0;j<n;j++)
    {
    if (Graph[i][j])
    {
     if (temp.x[j])
     {
      temp.cut--;
     }
     else
     {
      temp.cut++;
      temp.edges--;
     }
    }
    }
    temp.x[i] =1;
           temp.i++;
   Q.push(temp);
    if(E.cut+E.edges>bestcut)//界限条件
    {
               E.i++;
    Q.push(E);
    }
   }
   if(Q.size()==0)//队列为空跳出循环
   {
    break;
   }
   E = Q.top();
   Q.pop();
}
}
int main()
{
    intu,v;
cin>>n>>e;
for (int i=0;i<e;i++)
{
  cin>>u>>v;
   Graph[u-1][v-1] = 1;
   Graph[v-1][u-1] = 1;
}
   maxcut();
cout<<bestcut<<endl;
for (int k=0;k<n;k++)
{
  cout<<bestx[k]<<'';
}
cout<<endl;
return 0;
}

输入实例

7 18
1 4
1 5
1 6
1 7
2 3
2 4
2 5
2 6
2 7
3 4
3 5
3 6
3 7
4 5
4 6
5 6
5 7
6 7

输出实例:

12
1 1 1 0 1 0 0

0 0
原创粉丝点击