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,已經達到了滿足要求的點選和不選兩種情況的實現.

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