zoukankan      html  css  js  c++  java
  • 图着色问题

    图上的染色问题算是一个挺有名的NP-完全问题了吧

    题目描述

        给定无向连通图G 和M 种不同的颜色,用这些颜色为图G 的各顶点着色,每个顶点着一种颜色。如果有一种着色法使G 中每条边的2 个顶点着不同的颜色,则称这个图是M 可着色的。图的M 着色问题是对于给定图G 和M 种颜色,找出所有不同的着色法。对于给定的无向连通图G 和M 种不同的颜色,编程计算图的所有不同的着色法。


    输入

       第一行有3 个正整数N,K 和M,表示给定的图G 有N 个顶点和K 条边,M 种颜色。顶点编号为1,2……,N。接下来的K 行中,每行有2 个正整数U, V,表示图G 的一条边(U,V)。

      数据范围:1<N<=100 1<K<=2500 1<M<=6


    输出


      不同的着色方案数

    样例输入


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


    样例输出


      48

    我的解析:

        这道题是一道典型的搜索题,需要dfs和一点点优化(剪枝)。

      我们来看一下样例给的这张图。

        为什么是搜索?对于样例来说,每个点我们都有4种颜色可以选择,而在确定完一个点的颜色后又要选取其他点的颜色,并不能与它相连的点重复。于是马上想到要进行搜索。

        搜索的过程:对于每个点,枚举它可能被染的颜色。如果与它相连的点颜色和它相同,那么就换下一个颜色;如果哪个颜色也不能选,那就回到上一个点换颜色(回溯)……

      当确定完最后一个点的颜色后,这就是一个可行解,将答案增加1。

        我们在判断哪个点与这个点(编号为n)连接并颜色相同时,本来是要遍历一遍图上的点的,而这样会超时。其实不需要这样做。只需遍历从编号1 到 编号n-1 的点就行了,因为

      并没有确定编号n以后的点的颜色。这样相对于把点全遍历一遍,能更快一点,算是一个优化吧。

    我的代码:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int m,n,k;
    int map[105][105];
    int color[105];
    int ans;
    void a(int p)
    {
        if(p == n+1)
        {
            ans++;
            return;
        }
        else
        {
            for(int i=1;i<=m;i++)
            {
                int mmp = false;
                for(int j=1;j<=p;j++)
                {
                    if(map[p][j] == 1 && color[j] == i)
                    {
                        mmp = true;
                        break;
                    }
                }
                if(mmp == true) continue;
                color[p] = i;
                a(p+1);
                color[p] = 0;
            }
        }
    }
    int main()
    {
    //    freopen("color.in","r",stdin);
    //    freopen("color.out","w",stdout);
        scanf("%d%d%d",&n,&k,&m);
        for(int i=1;i<=k;i++)
        {
            int d1,d2;
            scanf("%d%d",&d1,&d2);
            map[d1][d2] = 1;
            map[d2][d1] = 1;
        }
        a(1);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    LeetCode Algorithm
    实现QObject与JavaScript通讯(基于QWebEngine + QWebChannel)
    Linux工具参考篇(网摘)
    GO 语言简介(网摘)
    Qt窗体引用window自带阴影边框效果
    无插件VIM编程技巧(网摘)
    ASP.NET 5基础之中间件
    ASP.NET Core 1.0基础之应用启动
    理解ASP.NET 5 Web Apps
    DNX 概览
  • 原文地址:https://www.cnblogs.com/Ch-someone/p/8682537.html
Copyright © 2011-2022 走看看