Maximum Clique

来源:互联网 发布:mac装win8还是win10 编辑:程序博客网 时间:2024/06/05 20:25

这里写图片描述

//题意:给定一张图,求最大团顶点数

注:

团:完全图(即每个点和其他各点间都有一条边)。

极大团:在给定的一张图中,若有一个团,在加入该团外任意一点后都不再是一个团,那么该团为极大团。

最大团:给定一张图,其中顶点个数最多的极大团就是最大团。

//思路:最大团模板(dp剪枝)

#include <iostream>#include <cstdio>#include <cmath>#include <string.h>#include <string>#include <cstdlib>#include <algorithm>using namespace std;int n;int map[60][60];int Set[60]; //存放点的编号int Ans; //最大团的顶点数int dp[60]; //dp用来剪枝//判断:该点是否和end之前保存在Set中的各点都相连bool judge(int end, int point){    int i;    for (i = 1; i < end; i++)    {        if (!map[Set[i]][point])            return false;    }    return true;}//depth:深度(也可以理解为顶点的个数) now:当前点的编号void dfs(int depth, int now) {    //剪枝:如果(团中当前顶点个数+当前加入的点到最后(n)的点的个数(n-now+1))比(现存的Ans)还小的话就剪掉    if (depth + n - now + 1 <= Ans || depth + dp[now] <= Ans)        return;    //从now判断到n    //如果该点能和该点之前保存在Set中的点构成团,就dfs它下一个点(递归)    for (int i = now; i <= n; i++)    {        if (judge(depth + 1, i))        {            Set[depth + 1] = i;            dfs(depth + 1, i + 1);        }    }    //更新最大团顶点数    if (depth > Ans)        Ans = depth;}int main(){    int i, j;    while (cin >> n&&n) //n==0 break    {        for (i = 1; i <= n; i++)        {            for (j = 1; j <= n; j++)            {                cin >> map[i][j];            }        }        //max_clique(最大团)        //dp剪枝        memset(dp, 0, sizeof(dp));        Ans = 0;        dp[n] = 1;        for (i = n - 1; i >= 1; i--)        {            Set[1] = i;            dfs(1, i + 1);            dp[i] = Ans;        }        cout << dp[1] << endl;    }    return 0;}
原创粉丝点击