hdu - 1530 Maximum Clique 最大團模板

給定無向圖G=(V,E),其中V是非空集合,稱爲頂點集;E是V中元素構成的無序二元組的集合,稱爲邊集,無向圖中的邊均是頂點的無序對,無序對常用圓括號“( )”表示。

如果U  V,且對任意兩個頂點u,v∈U有(u,v)∈E,則稱U是G的完全子圖。G的完全子圖U是G的團。G的最大團是指G的最大完全子圖。

如果U∈V且對任意u,v∈U有(u,v)不屬於E,則稱U是G的空子圖。G的空子圖U是G的獨立集當且僅當U不包含在G的更大的空子圖中。G的最大獨立集是G中所含頂點數最多的獨立集。

對於任一無向圖G=(V,E),其補圖G'=(V',E')定義爲:V'=V,且(u,v)∈E'當且僅當(u,v)∉E。

如果U是G的完全子圖,則它也是G'的空子圖,反之亦然。因此,G的團與G'的獨立集之間存在一一對應的關係。特殊地,U是G的最大團當且僅當U是G'的最大獨立集。

通俗點講就是在一個無向圖中找出一個點數最多的完全圖。 

最大獨立集 = 補圖的最大團

最大團 = 補圖的最大獨立集

鏈接:hdu - 1530  

最大團模板:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#define inf 0x3f3f3f3f

using namespace std;

const int maxn = 1005;
/*
最大團 = 補圖G的最大獨立集數
———>最大獨立集數 = 補圖G'的最大團
*/
//最大團模板
bool mp[maxn][maxn];//mp爲圖的鄰接表(從1開始)
int ans, cnt[maxn], group[maxn], n, m, vis[maxn];//ans表示最大團,cnt[maxn]表示當前最大團的節點數,group[maxn]用以尋找一個最大團集合
bool dfs(int u, int pos) {
    //u爲當從前頂點開始深搜,pos爲深搜深度(即當前深搜樹所在第幾層的位置)
    for(int i = u + 1; i <= n; i++) {
        int j;
        //按遞增順序枚舉頂點
        if(cnt[i] + pos <= ans) //剪枝
            return 0;
        if(mp[u][i]) {
            // 與目前團中元素比較,取 Non-N(i)
            for(j = 0; j < pos; j++)
                if(!mp[i][vis[j]])
                    break;
            if(j == pos) {
                // 若爲空,則皆與 i 相鄰,則此時將i加入到 最大團中
                vis[pos] = i;//深搜層次也就是最大團的頂點數目,vis[pos] = i表示當前第pos小的最大團元素爲i(因爲是按增順序枚舉頂點 )
                if(dfs(i, pos + 1))
                    return 1;
            }
        }
    }
    if(pos > ans) {
        for(int i = 0; i < pos; i++)
            group[i] = vis[i]; // 更新最大團元素
        ans = pos;
        return 1;
    }
    return 0;
}
void maxclique() {//求最大團
    ans = -1;
    for(int i = n; i > 0; i--) {
        vis[0] = i;
        dfs(i, 1);
        cnt[i] = ans;
    }
}
int main()
{
    while(~scanf("%d", &n)) {
        if(n == 0) break;
        memset(mp, 0, sizeof(mp));
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                 scanf("%d", &mp[i][j]);
        maxclique();//求最大團
        if(ans < 0)
            ans = 0;//ans表示最大團
        printf("%d\n", ans);
        /*for(int i = 0; i < ans; i++)
            printf( i == 0 ? "%d" : " %d", group[i]); //group[maxn]用以尋找一個最大團集合
        if( ans > 0 ) puts("");*/
    }
}

 

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