uva 193 Graph Coloring

原题:
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.
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

中文:
给你一个图,让你用黑色和白色给这个图染色。黑色的点不能相邻,问你最多能有多少个黑点?
!!!注意,这个图不一定是连通图们可能有很多连通分量

#include <bits/stdc++.h>
using namespace std;
vector<int> G[111];
int n,k,solve[111],tmp[111],color[111],ans;
void ini()
{
    memset(tmp,0,sizeof(tmp));
    for(int i=1;i<=n;i++)
        G[i].clear();
        ans=0;
}
void dfs(int x,int tmp[])
{
    int color[101];
    if(x==n)
    {
        int cnt=0;
        for(int i=1;i<=n;i++)
            if(tmp[i]==1)
                cnt++;
        if(cnt>ans)
        {
            memcpy(solve,tmp,sizeof(solve));
            ans=cnt;
        }
    }
    else
    {
        for(int i=1;i<=n;i++)
        {
            if(tmp[i]==0)
            {
                memcpy(color,tmp,sizeof(color));
                color[i]=1;
                int cnt=1;
                for(int j=0;j<G[i].size();j++)
                {
                    if(color[G[i][j]]==0)
                    {
                        color[G[i][j]]=-1;
                        cnt++;
                    }
                }
                dfs(x+cnt,color);
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        ini();
        for(int i=1;i<=k;i++)
        {
            int a,b;
            cin>>a>>b;
            G[a].push_back(b);
            G[b].push_back(a);
        }
        dfs(0,tmp);
        cout<<ans<<endl;
        /*
        for(int i=1;i<=n;i++)
        {
            if(solve[i]==1&&ans>0)
            {
                if(ans==1)
                    cout<<i<<endl;
                else
                    cout<<i<<" ";
                ans--;
            }
        }*/
        k=0;
        for(int i=1;i<=n;i++)
            if(solve[i]==1)
            {
                if(k++)
                    cout<<" ";
                cout<<i;
            }
            cout<<endl;

    }
    return 0;
}

解答:
思路很简单,染成黑色的节点周围和它相邻的节点肯定都是白色点。暴力解决即可,但是怎么写都是wa,后来看别人代码知道了图可能是不连通的。

有一个优化的想法,如果计算黑色点最大,可能不太好像优化的方法。但是反过来可以去想计算白色的点最少,记录上一次白色点最少的结果,下一次枚举图中的白色点的个数的时候,如果枚举到半路就已经比上次得到的结果多了,那就可以剪枝了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值