zoukankan      html  css  js  c++  java
  • GHOJ 682 图的m着色问题

    题目背景

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

    题目描述

      对于给定的无向连通图G和m种不同的颜色,编程计算图的所有不同的着色法。

    输入格式

      第1行有3个正整数n,k 和m,表示给定的图G有n个顶点和k条边,m种颜色。顶点编号为1,2,…,n。接下来的k行中,每行有2个正整数u,v,表示图G 的一条边(u,v)。

    输出格式

       程序运行结束时,将计算出的不同的着色方案数输出。

    输入样例

    5 8 4

    1 2

    1 3

    1 4

    2 3

    2 4

    2 5

    3 4

    4 5

    输出样例

    48

    说明

      n<=100;k<=2500;

      在n很大时保证k足够大。

      保证答案不超过20000。

    题解

      别的剪枝不多说了。在这一题中,我们要搜索的起点其实只用搜一种颜色,最后输出的时候再乘上$m$即可(乘法原理)。

    #include <iostream>
    
    #define MAX_N (100 + 5)
    #define MAX_K (2500 + 5)
    #define MAX_M (2500 + 5)
    
    using namespace std;
    
    struct Edge
    {
        int to;
        int next;
    };
    
    int n, k, m;
    int h[MAX_N], tot;
    Edge e[MAX_K + MAX_K];
    int c[MAX_N][MAX_M];
    int ans;
    
    inline void Add_Edge(int u, int v)
    {
        e[++tot].to = v;
        e[tot].next = h[u];
        h[u] = tot;
        return;
    }
    
    void DFS(int u)
    {
        if(u > n)
        {
            ++ans;
            return;
        }
        for(register int i = 1; i <= m; ++i)
        {
            if(c[u][i]) continue;
            for(register int j = h[u]; j; j = e[j].next)
            {
                ++c[e[j].to][i]; 
            }
            DFS(u + 1);
            for(register int j = h[u]; j; j = e[j].next)
            {
                --c[e[j].to][i]; 
            }
        }
        return;
    }
    
    int main()
    {
        cin >> n >> k >> m;
        int u, v; 
        for(register int i = 1; i <= k; ++i)
        {
            cin >> u >> v;
            Add_Edge(u, v);
            Add_Edge(v, u);    
        }
        for(register int i = h[1]; i; i = e[i].next)
        {
            ++c[e[i].to][1];
        }
        DFS(2);
        cout << ans * m;
        return 0;
    } 
    参考程序
  • 相关阅读:
    UltraEdit程序设置添加到右键菜单
    UltraEdit加入到右键菜单中
    vim常用命令
    Linux vi命令大全
    vi/vim 计算搜寻关键字数量
    vi 删除全部内容
    vi中全选的命令或者快捷方式
    VI打开和编辑多个文件的命令
    vi/vim 查找替换使用方法
    VMware workstation 与 VMware GSX Server 的区别
  • 原文地址:https://www.cnblogs.com/kcn999/p/10988665.html
Copyright © 2011-2022 走看看