POJ 1419 最大独立集(即最大团)

来源:互联网 发布:手机怎样申请淘宝店铺 编辑:程序博客网 时间:2024/06/05 07:16

POJ 1419

题目链接:

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17391

题意:

给一个图,要求把图中点染色,规则是一个点如果染成黑色,则有边相连的其他点不能染成黑色。

问怎样选取最多的点染成黑色。输出点个数和选取方案。

思路:

最大独立集:一个图中最大的互相没有边相连的点集。

结论:原图的最大独立集等于补图的最大团

源码:

#include <cstdio>

#include <cstring>

#include <cmath>

#include <cstdlib>

#include <algorithm>

#include <iostream>

#include <string>

#include <vector>

using namespace std;

const int MAXN = 100 + 5;

int gra[MAXN][MAXN];

int vis[MAXN];

int val[MAXN];

int ans[MAXN], cnt;

int n, m;

bool check(int mark)

{

    for(int i = 1 ; i < mark ; i++)

        if(vis[i] && gra[i][mark] == 0)

            return false;

    return true;

}

void DFS(int mark, int num)

{

    if(num > cnt){

        cnt = num;

        int now = 0;

        for(int i = 1 ; i <= n ; i++){

            if(vis[i])

                ans[now++] = i;

        }

    }

    for(int i = mark + 1 ; i <= n ; i++){

        if(check(i)){

            vis[i] = 1;

            DFS(i, num + 1);

            vis[i] = 0;

        }

    }

}

int main()

{

    int t;

    scanf("%d", &t);

    while(t--){

        scanf("%d%d", &n, &m);

        for(int i = 1 ; i <= n ; i++)

            for(int j = 1 ; j <= n ; j++)

                gra[i][j] = 1;

        int u, v;

        for(int i = 0 ; i < m ; i++){

            scanf("%d%d", &u, &v);

            gra[u][v] = gra[v][u] = 0;

        }

        cnt = 0;

        memset(vis, 0, sizeof(vis));

        for(int i = 1 ; i <= n ; i++){

            vis[i] = 1;

            DFS(i, 1);

            vis[i] = 0;

        }

        printf("%d\n", cnt);

        int f = 1;

        for(int i = 0 ; i < cnt ; i++){

            if(f)   f = 0;

            else    printf(" ");

            printf("%d", ans[i]);

        }

        printf("\n");

    }

    return 0;

}

 

0 0
原创粉丝点击