最大团问题-分支限界算法

来源:互联网 发布:webstorm mac 破解版 编辑:程序博客网 时间:2024/05/21 05:24

算法设计与分析课上,老师布置了一个讲解最大团的分支限界算法的问题,在查阅了资料以后,写的代码。

最大团,就是一个图里所有团中最大的一个。团,一个最大的完全子图(改完全子图不包含在其他更大的完全子图中)。

算法原理:

比如对于一个图g,它已经包含了{1,2}并且,我们知道它是按照1,2的顺序放入的,即最后放入的那个点是2,搜索原图所有的顶点,找到一个点x使得:2与x相连,x与g原先有的顶点相连(x与1相连)。那么对于图g的下一个图h就有{1,2,x}放入队列。继续寻找下一个顶点y。依次类推,直到队列为空。

#include <iostream>#include<cstdio>#include<algorithm>#include<queue>#include<cstring>using namespace std;struct node//定义结构体{    int last;//最后加入的点    int v[10];//v[i]=1表示顶点i已经在该集合中v[i]=0则相反    int num;//顶点个数    node()//构造函数,初始化    {        memset(v,0,sizeof(v));        num=0;    }};int ans,n;int a[11][11];queue<node*>q;void bfs(node *head)//分支界限算法{    while(!q.empty())q.pop();    q.push(head);    int i,j;    while(!q.empty())    {        node *tem=q.front();//取对顶        ans=max(ans,tem->num);        if(ans==n)break;        q.pop();        int t=tem->last;        for(i=1; i<=n; i++)//搜索所有的顶点        {            if(i==t)continue;            if(a[t][i]==1&&tem->v[i]==0)//如果该点还未加入该集合并且该点与最后加入的点有连线            {                for(j=1; j<=n; j++)//判断该点是否与已经加入该集合的每一个点有连线                {                    if(tem->v[j]==1&&a[i][j]==0)break;                }                if(j>n)//如果该点与该集合的每一个点有连线,在该集合中加入该点                {                    node *nod=new node();                    for(int k=1; k<=n; k++)//初始化                    {                        nod->v[k]=tem->v[k];                    }                    nod->last=i;                    nod->v[i]=1;                    nod->num=tem->num+1;                    q.push(nod);//新节点推入该队列                }            }        }    }}int main(){    int m,i,j,k;    cout<<"请输入顶点个数";    cin>>n;    for(i=1; i<=n; i++)    {        cout<<"请输入与点 "<<i<<" 相关的所有的点的连线情况:";        for(j=1; j<=n; j++)        {            cin>>a[i][j];        }    }    for(i=0; i<=n; i++)//根节点与所有的点相连        a[i][0]=a[0][i]=1;    node *head=new node();    head->last=0;    ans=0;    bfs(head);    cout<<"最大团的个数为:";    cout<<ans<<endl;    return 0;}/*50 1 0 1 11 0 1 0 10 1 0 0 11 0 0 0 11 1 1 1 0*/


0 0