#include <iostream>
#include <fstream>
#include <queue>
#include <algorithm>
using namespace std;
const int MAX = 50;
int G[MAX][MAX];
int bestx[MAX];
int w[MAX]; //顶点的权
int n, e; //电路板数,连接块数
class Node
{
public:
int dep; //当前层
int cut; //割边数量
int e; //剩余边的数量
int *x; //解向量
Node(int d, int c, int ee)
{
x = new int[n+1];
dep = d;
cut = c;
e = ee;
}
//割边数大的先出队列
bool operator < (const Node &node) const
{
return cut < node.cut;
}
};
priority_queue<Node> q;
//添加结点
void addNode(Node enode, bool isLeft)
{
Node now(enode.dep+1, enode.cut, enode.e);
copy(enode.x, enode.x+n+1, now.x);
if(isLeft)
{
now.x[now.dep] = 1;
for(int j=1; j<=n; j++)
if(G[now.dep][j])
if(now.x[j] == 0) //如果当前顶点在割集中,但边的另一个顶点不在割集
{
now.cut++; //割边的数量增加
now.e--; //剩余边的数量减少
}
else
now.cut--;
}
else
{
now.x[now.dep] = 0;
now.e--;
}
q.push(now);
}
int search()
{
Node enode(0, 0, e);
for(int j=1; j<=n; j++)
enode.x[j] = 0;
int best = 0;
while(true)
{
if(enode.dep>n)
{
if(enode.cut > best)
{
best = enode.cut;
copy(enode.x, enode.x+n+1, bestx);
break;
}
}
else
{
addNode(enode, true);
if(enode.cut + enode.e > best)
addNode(enode, false);
}
if(q.empty())
break;
else
{
enode = q.top();
q.pop();
}
}
return best;
}
int main()
{
ifstream fin("最大割.txt");
cout << "输入图的顶点数:";
fin >> n; cout << n;
cout << "\n输入图的边数:";
fin >> e; cout << e;
cout << "\n输入每条边:\n";
int a, b, i;
memset(G, 0, sizeof(G));
for(i=1; i<=e; i++)
{
fin >> a >> b;
G[a][b] = G[b][a] = 1;
cout << a << " " << b << endl;
}
cout << "\n最大割的边数为:" << search();
cout << "\n顶点集 为:\n" ;
for(i=1; i<=n; i++)
cout << bestx[i] << " ";
cout << endl;
cout << endl;
fin.close();
return 0;
}
无向图的最大割问题
最新推荐文章于 2021-08-29 18:23:21 发布