#include "cstdio"
#include "queue"
#include "cstring"
#define MAX 20
using namespace std;
int n; //城市数量
int x[MAX]; //解向量
struct Node
{
int cn; //当前团中的顶点数
int un; //当前团最大顶点的上界,优先级
int level; //结点在子集空间树中所处的层次
//最大顶点上界最大的结点先出队列
bool operator < (const Node &node) const
{
return un < node.un;
}
};
priority_queue<Node> pq;
void EnQueue(int cn, int un, int level)
{
Node node;
node.cn = cn;
node.un = un;
node.level = level;
pq.push(node);
}
int maxClique(int a[6][6])
{
memset(x, 0, sizeof(x));
int bestn = 0; //最大团中顶点数最优值
int i = 1; //结点所在层次
int cn = 0; //当前最大团中顶点数
int j;
int ok;
Node node; //当前扩展结点
while(i!=n+1) //如果还没有到叶结点
{
ok = 1;
//检查当前顶点是否与团中其它顶点相连,如果相连,可以加入团
for(j=1; j<i; j++)
if(x[j] && !a[i][j])
{
ok = 0;
break;
}
if(ok) //搜索左子树
{
if(cn+1>bestn) //如果加入顶点后的顶点数比当前最优值更优
bestn = cn+1; //更新最优值
x[i] = 1; //顶点加入团
EnQueue(cn+1, cn+n-i+1, i+1);
}
if(cn+n-i>=bestn) //如果可能产生最优值,搜索右子树
{
//x[i] = 0; //不加入
EnQueue(cn, cn+n-i, i+1);
}
//取下一层扩展结点
node = pq.top();
pq.pop();
cn = node.cn;
i = node.level;
}
return bestn;
}
int main()
{
n = 5;
int a[6][6] = {
{0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 1, 1},
{0, 1, 0, 1, 0, 1},
{0, 0, 1, 0, 0, 1},
{0, 1, 0, 0, 0, 1},
{0, 1, 1, 1, 1, 0}
};
printf("邻接矩阵为:\n");
int i, j;
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
printf("%d ", a[i][j]);
printf("\n");
}
int bestn = maxClique(a);
printf("最大团顶点数:%d\n", bestn);
printf("解向量之一为:\n");
for(i=1; i<=n; i++)
printf("%d ", x[i]);
printf("\n");
return 0;
}
最大团问题
最新推荐文章于 2022-11-16 12:14:25 发布