zoukankan      html  css  js  c++  java
  • 求图的最大团问题

    搜索解空间:

    1、约束条件:

    只要第t个结点和前t-1个结点中被选中的结点都有边相连,则放入团中,否则不能放入

    2、限界条件:

    当第t个结点不能放入团中时,要判断假设下面的n-t个结点全放入团中加上当前以及放入的结点cn个的和:cn+n-t是否大于最优值bestn,若大于,则有必要继续搜索;

    若小于等于,则没必要继续搜索,当前的bestn就是最优值,搜索可以结束了

    3、搜索过程:从根节点出发,以深度优先搜索的方式进行,每次搜索一个结点,判断约束条件,满足则继续向其左分支向下继续搜索;如果不满足,则要判断限界条件,如果满足限界条件,则继续向其右子树向下继续搜索,不满足则当前bestn即是最优值,搜索结束。

     1 #include <iostream>
     2 #include <string.h> 
     3 using namespace std;
     4 const int N=100;
     5 int a[N][N];//图用邻接矩阵表示 
     6 bool x[N];//存储每个点是否加入团 
     7 bool bestx[N];//记录每个结点是否放入,记录最优解 
     8 int bestn;//记录最大值 
     9 int cn;//当前已放入团中的结点数量 
    10 int n,m;//n为结点数,m为图中的边数
    11 bool Place(int t){//判断第t个结点是否可以放入最大团 
    12     bool ok=true;
    13     for(int j=1;j<t;j++){
    14         if(x[j]&&a[t][j]==0){//x[j]是第j个点放入了最大团中,a[t][j]是前面放入的t-1个结点是否和第t个点有相连边 
    15             ok=false;
    16             break;
    17         }
    18     }
    19     return ok;
    20 } 
    21 void Backtrack(int t){
    22     if(t>n){//到达叶结点 
    23         bestn=cn;//将当前团个数设为最优值 
    24         for(int i=1;i<=n;i++){//并寻找最优解:由哪些结点构成 
    25             bestx[i]=x[i];
    26         }
    27         return ;
    28     }
    29     if(Place(t)){//满足约束条件,进入左子树 
    30         cn++;//放入 
    31         x[t]=1;//设为放入 
    32         Backtrack(t+1);//进入下一层(左子树) 
    33         cn--;//回溯回来cn-- ,怎么加的怎么减去 
    34     }
    35     if(cn+n-t>bestn){//满足限界条件,进入右子树 
    36         x[t]=0;//不放入,cn不变 
    37         Backtrack(t+1);//进入下一层(右子树) 
    38     }
    39 }
    40 int main(){
    41     int u,v;
    42     cout<<"结点数n:";
    43     cin>>n;
    44     cout<<"边数m:";
    45     cin>>m;
    46     memset(a,0,sizeof(a));
    47     cout<<"请输入有边相连的两点:";
    48     for(int i=1;i<=m;i++){
    49         cin>>u>>v;
    50         a[u][v]=a[v][u]=1;
    51     }
    52     bestn=0;
    53     cn=0;
    54     Backtrack(1);
    55     cout<<"最大团个数为:"<<bestn<<endl;
    56     cout<<"分别为:";
    57     for(int i=1;i<=n;i++)
    58         if(bestx[i]==1)
    59             cout<<i<<" ";
    60     return 0;
    61 } 
  • 相关阅读:
    .OBJ est1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
    线程详细剖析(四)
    线程详细剖析(三)
    线程详细剖析(二)
    线程详细剖析(一)
    CAN总线相关的几个gitlab代码
    进程详细剖析(三)
    C++实现多级排序
    C/C++读写二进制文件
    C++11新特性
  • 原文地址:https://www.cnblogs.com/nilbook/p/13971282.html
Copyright © 2011-2022 走看看