P2819 图的m着色问题 洛谷

https://www.luogu.org/problem/show?pid=2819

题目背景

给定无向连通图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)。

输出格式:

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

输入输出样例

输入样例#1:

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

输出样例#1:

48

说明

n<=100;k<=2500;

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

保证答案不超过20000。

 

 1 #include <algorithm>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 int n,k,m,fx,fy,ans;
 7 int color[2505];
 8 int burn[2505][2505];
 9 
10 bool judge(int x,int col)
11 {
12     //枚举每个点的染色情况 
13     for(int i=1;i<=n;i++)
14     {
15         //不看当前点 
16         if(x==i) continue;
17         //两个点首先要连接,如果颜色相同的话,那么就无法染编号为i的颜色 
18         if(burn[x][i]==1&&color[i]==col)
19             return 0;
20     }
21     //两点不连接或者连到的点颜色不与编号为i的点的颜色相同,就可以染色 
22     return 1;
23 }
24 
25 void DFS(int now)
26 {
27     //如果当前染够了n个点,退出,找下一个方案;; 
28     if(now==n+1)
29     {
30         ans++;
31         return ;
32     }
33     //枚举可以染上的颜色的编号 
34     for(int i=1;i<=m;i++)
35     {
36         //如果当前的点没有染色,就判断它是否可以染编号为i的颜色 
37         if(!color[now]&&(judge(now,i)))
38         {
39             //染上枚举到的颜色 
40             color[now]=i;
41             //染下一个点 
42             DFS(now+1);
43             //如果始终无法染够n个点,或者完成了一种方案,回溯;; 
44             color[now]=0;
45         }
46     }
47 }
48 
49 int main()
50 {
51     cin>>n>>k>>m;
52     for(int i=1;i<=k;i++)
53     {
54         cin>>fx>>fy;
55         //首先,把图建出来;;; 
56         burn[fx][fy]=burn[fy][fx]=1;
57     }
58     DFS(1);
59     //从第一个点开始找;; 
60     cout<<ans;
61     return 0;
62 }
带解析

 

无解析:

#include <algorithm>
#include <iostream>

using namespace std;

int n,k,m,fx,fy,ans;
int color[2505];
int burn[2505][2505];

bool judge(int x,int col)
{
    for(int i=1;i<=n;i++)
    {
        if(x==i) continue;
        if(burn[x][i]==1&&color[i]==col)
            return 0;
    }
    return 1;
}

void DFS(int now)
{
    if(now==n+1)
    {
        ans++;
        return ;
    }
    for(int i=1;i<=m;i++)
    {
        if(!color[now]&&(judge(now,i)))
        {
            color[now]=i;
            DFS(now+1);
            color[now]=0;
        }
    }
}

int main()
{
    cin>>n>>k>>m;
    for(int i=1;i<=k;i++)
    {
        cin>>fx>>fy;
        burn[fx][fy]=burn[fy][fx]=1;
    }
    DFS(1);
    cout<<ans;
    return 0;
}

 

posted @ 2017-03-26 11:41  Aptal丶  阅读(350)  评论(0编辑  收藏  举报