回溯法--最大团问题

问题描述

给定无向图G(N,E),含有n个结点,m条边。现在有以下定义:
完全子图:原图的一个子图,并且该子图是一个完全图。
完全图:每对不同的顶点之间都恰连有一条边相连。
团:它是一个完全子图,并且它不包含在任何其它更大的完全子图中。
最大团:包含结点最多的团。
请计算G的一个最大团。
输入第一行2个整数n,m;
接下来m行,每行两个数,u,v表示u,v结点有一条无向边。
输出2行:
第一行一个整数x表示最大团中结点个数。
第二行x个整数,最大团中结点编号,若答案不唯一,打印任意一个即可。

解决思路

  • 待解决

代码实现

/*
3 3
1 2 
1 3 
2 3 

3
1 2 3
*/
#include <iostream>
#include <cmath>
using namespace std;

const int N = 10;
bool a[N][N];			// 图G的邻接矩阵
int n;				// 图G的顶点数
bool x[N];			// 当前解
int bestx[N];			// 当前最优解
int cn;				// 当前顶点数
int bestn;			// 当前最大顶点数
int m;				// 图G的边数

void BackTrack(int i)
{
    if(i > n)
    {
        bestn = cn;
        cout << bestn << endl;
        for(int i = 1; i <= n; i++)
            if(x[i]) 
                cout << i << " ";
        cout << endl;
        return ;
    }

    bool ok = true;
    for(int j = 1; j < i; j ++ )
    {
        if(x[j] && !a[j][i])  //i与j不相连
        {
            ok = false;
            break;
        }
    }
    if(ok)  //进入左子树
    {
        cn ++;
        x[i] = true;
        BackTrack(i + 1);
        x[i] = false;
        cn --;
    }
    if(cn + n - i > bestn)  //剪枝
    {
        x[i] = false;
        BackTrack(i + 1);
    }
}

int main()
{
	cin >> n >> m;
	for(int i = 1; i <= m; i ++ )
	{
		int x, y;
		cin >> x >> y;
		a[x][y] = true;
		a[y][x] = true;
	}

	BackTrack(1);
/*
	cout << bestn << endl;
	for(int i = 1; i <= n; i++)
        if(x[i]) 
            cout << i << " ";
	cout << endl;
*/ 
	return 0;
} 
posted @   esico  阅读(190)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示