POJ1419 Graph Coloring------(最大独立集-----补图最大团)

版权声明:本文为博主原创文章,转载请标明原博客。 https://blog.csdn.net/sdau_fangshifeng/article/details/88427140

题目链接:

http://poj.org/problem?id=1419

Graph Coloring

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 6047   Accepted: 2786   Special Judge

Description

You are to write a program that tries to find an optimal coloring for a given graph. Colors are applied to the nodes of the graph and the only available colors are black and white. The coloring of the graph is called optimal if a maximum of nodes is black. The coloring is restricted by the rule that no two connected nodes may be black. 


 
Figure 1: An optimal graph with three black nodes 

Input

The graph is given as a set of nodes denoted by numbers 1...n, n <= 100, and a set of undirected edges denoted by pairs of node numbers (n1, n2), n1 != n2. The input file contains m graphs. The number m is given on the first line. The first line of each graph contains n and k, the number of nodes and the number of edges, respectively. The following k lines contain the edges given by a pair of node numbers, which are separated by a space.

Output

The output should consists of 2m lines, two lines for each graph found in the input file. The first line of should contain the maximum number of nodes that can be colored black in the graph. The second line should contain one possible optimal coloring. It is given by the list of black nodes, separated by a blank.

Sample Input

1
6 8
1 2
1 3
2 4
2 5
3 4
3 6
4 6
5 6

Sample Output

3
1 4 5

Source

Southwestern European Regional Contest 1995

 题意:

由于相邻节点颜色不同,同种颜色的节点就组成了一个独立集,显然题目要求计算图的最大独立子集。

而 图的最大独立子集 = 补图的最大团

This is the code:

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<sstream>
#include<stack>
#include<string>
#include<set>
#include<vector>
using namespace std;
#define PI acos(-1.0)
#define pppp cout<<endl;
#define EPS 1e-8
#define LL long long
#define ULL unsigned long long     //1844674407370955161
#define INT_INF 0x3f3f3f3f      //1061109567
#define LL_INF 0x3f3f3f3f3f3f3f3f //4557430888798830399
// ios::sync_with_stdio(false);
// 那么cin, 就不能跟C的 scanf,sscanf, getchar, fgets之类的一起使用了。
const int dr[]={0, 0, -1, 1, -1, -1, 1, 1};
const int dc[]={-1, 1, 0, 0, -1, 1, -1, 1};
int read()//输入外挂
{
    int ret=0, flag=0;
    char ch;
    if((ch=getchar())=='-')
        flag=1;
    else if(ch>='0'&&ch<='9')
        ret = ch - '0';
    while((ch=getchar())>='0'&&ch<='9')
        ret=ret*10+(ch-'0');
    return flag ? -ret : ret;
}
bool G[105][105];
bool vis[105];
vector<int > v;
int n;
int ans;
int cnt;
void DFS(int x)
{
    if(x>n)//更新最大团
    {
        v.clear();
        ans=cnt;
        for(int i=1;i<=n;++i)
            if(vis[i])
                v.push_back(i);
        return ;//注意return
    }
    bool flag=true;
    for(int i=1;i<x;++i)
    {
        if(vis[i]&&!G[i][x])//vis[i]表示i进如最大图了,!G[i][x]表示没有i--x的边
        {
            flag=false;
            break;
        }
    }
    if(flag)//x满足条件,进行深搜
    {
        vis[x]=true;
        cnt++;
        DFS(x+1);
        vis[x]=false;//回溯
        cnt--;
    }
    if(cnt+(n-x)>ans)//剪纸进行搜索,如果不将当前点加入团中,须满足剩下的所有的点加上当前团中的点比已知解更优。
        DFS(x+1);
}
int main()
{
    //freopen("D:\\chnegxubianji\\inORout\\in.txt", "r", stdin);
    //freopen("D:\\chnegxubianji\\inORout\\out.txt", "w", stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ans=0;
        cnt=0;
        memset(G,true,sizeof(G));
        memset(vis,false,sizeof(vis));
        int k;
        scanf("%d%d",&n,&k);
        while(k--)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            G[u][v]=0;//补图
            G[v][u]=0;
        }

        DFS(1);
        printf("%d\n",ans);
        for(int i=0;i<v.size();++i)
            printf("%d ",v[i]);
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sdau_fangshifeng/article/details/88427140