POJ1419 & 最大团

题意:

  求一个图的最大点独立集.
SOL:

  转化为补图的最大团,最大团似乎是一个NP问题,那么只好爆搜了.

  补一补图论基础,代码不想打了,来自某blog

  

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
using namespace std;

int N, M, mp[105][105];
int ret, cnt, opt[105], st[105];

void dfs(int x) {
    if (x > N) { // 如果枚举了所有的节点 
        ret = cnt;
        memcpy(opt, st, sizeof (st)); // 用一个更大的极大团替代原有的极大团 
        return;
    }
    int flag = true;
    for (int i = 1; i < x; ++i) { // 检测新加入的点是否到团中的其他节点都存在一条边 
        if (st[i] && !mp[i][x]) {
            flag = false;
            break;
        }
    }
    if (flag) { // 如果该节点满足在这个团中 
        st[x] = 1, ++cnt; // 该节点被加入到完全子图中去
        dfs(x + 1);
        st[x] = 0, --cnt;
    }
    if (cnt+N-x > ret) { // 跳过x节点进行搜索同时进行一个可行性判定 
        dfs(x + 1);
    }
}

int main() {
    int T, x, y;
    scanf("%d", &T);
    while (T--) {
        ret = cnt = 0;
        scanf("%d %d", &N, &M);
        memset(st, 0, sizeof (st));
        for (int i = 0; i < 105; ++i) {
            fill(mp[i], mp[i]+105, 1);
        }
        while (M--) {
            scanf("%d %d", &x, &y);
            mp[x][y] = mp[y][x] = 0;
        }
        dfs(1);
        printf("%d\n", ret);
        for (int i = 1, j = 0; i <= N; ++i) {
            if (opt[i]) {
                printf(j == 0 ? "%d" : " %d", i);
                ++j;
            }    
        }
        puts("");
    }
    return 0;    
}

 

posted @ 2016-03-25 15:12  YCuangWhen  阅读(161)  评论(0编辑  收藏  举报