Maximum Clique-最大团dfs

Maximum Clique
问题来源:hdu-1530

Problem Description
Given a graph G(V, E), a clique is a sub-graph g(v, e), so that for all vertex pairs v1, v2 in v, there exists an edge (v1, v2) in e. Maximum clique is the clique that has maximum number of vertex.
 
Input
Input contains multiple tests. For each test:
The first line has one integer n, the number of vertex. (1 < n <= 50)
The following n lines has n 0 or 1 each, indicating whether an edge exists between i (line number) and j (column number).
A test with n = 0 signals the end of input. This test should not be processed.
 
Output
One number for each test, the number of vertex in maximum clique.

Sample Input
5
0 1 1 0 1
1 0 1 1 1
1 1 0 1 1
0 1 1 0 1
1 1 1 1 0
0

Sample Output
4

源代码:
#include<iostream>
#include<cstring>
using namespace std;

const int MAX = 55;
int N , maximum , S[MAX] , map[MAX][MAX];
//S是目前加入点的集合

void dfs( int now , int num );

int main( ){

    while( cin>>N && N ){
        maximum = 0;
        for( int i=0 ; i<N ; i++ )
            for( int j=0 ; j<N ; j++ )
                cin>>map[i][j];
        dfs( 0 , 0 );    //从0号点开始搜索,目前集合中点的个数为0
        cout<<maximum<<endl;
    }

    return 0;
}

void dfs( int now , int num ){
    int u , i , sign;

    if( num > maximum )    //剪枝函数-约束函数
        maximum = num;

    if( num+( N-now )<=maximum )    //剪枝函数-限界函数
        return ;

    for( u=now ; u<N ; u++ ){    //对于即将加入u这个点来说
        int flag = 1;    //假设满足加入条件(边均相连)

        for( i=0 ; i<num ; i++ ){
            if( !map[u][S[i]] ){    //有没连的边就flag赋值为0
                flag = 0;
                break;
            }
        }

        if( flag ){    //可以加入
            S[num] = u;    //加入集合
            dfs( u+1 , num+1 );    //继续深搜
        }
    }
}

代码分析:代码就是很简单的dfs搜索,几乎没有优化,不过增加参数num非常有用,就不用判断该点(可以加入团集合中)是否要加入(两次dfs)了,因为S[num]=u;直接可以把之前搜到的S[num]值覆盖掉,间接性达到了选和不选的两重情况判断.

比如说该图:

当1搜索到2时满足加入条件,把2也加入到集合中,下一轮搜索到3的时候S[2]=3;相当于不选2直接选3,已经达到了满足要求的点选和不选两种情况的实现.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章