华师一附中OI组

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1841|回复: 5
打印 上一主题 下一主题

P2819 图的m着色问题

[复制链接]

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
跳转到指定楼层
楼主
发表于 2018-5-26 21:05:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
https://www.luogu.org/problemnew/show/P2819

题目背景
给定无向连通图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。
回复

使用道具 举报

9

主题

89

帖子

292

积分

华一学生

积分
292
沙发
发表于 2018-5-31 22:11:25 | 只看该作者
  1. #include<iostream>
  2. using namespace std;
  3. int n,k,m,ans=0;///n个点 k条边 m种颜色
  4. const int mx=110;
  5. int a[mx];///颜色
  6. bool b[mx][mx];///b判断两点是否连通
  7. bool check(int x)
  8. {
  9.     for (int ix=1;ix<=n;ix++)
  10.     {
  11.         if (b[ix][x]&&a[x]==a[ix])
  12.             return false;
  13.     }
  14.     return true;
  15. }
  16. void dfs(int i)
  17. {
  18.     if (i>=n+1) ans++;
  19.     else for (int j=1; j<=m; j++)
  20.         {
  21.             a[i]=j;///第i个顶点填第j种颜色
  22.             if (check(i))///如果可以
  23.                 dfs(i+1);
  24.             a[i]=0;
  25.         }
  26. }
  27. int main()
  28. {
  29.     cin>>n>>k>>m;
  30.     for (int i=1; i<=k; i++)
  31.     {
  32.         int x,y;
  33.         cin>>x>>y;
  34.         b[x][y]=true;
  35.         b[y][x]=true;///连通
  36.     }
  37.     dfs(1);
  38.     cout<<ans;
  39.     return 0;
  40. }
复制代码
回复 支持 反对

使用道具 举报

9

主题

89

帖子

292

积分

华一学生

积分
292
板凳
发表于 2018-5-31 22:12:27 | 只看该作者
不确定是否要用“图论”~~~~
回复 支持 反对

使用道具 举报

7

主题

27

帖子

91

积分

注册会员

Rank: 2

积分
91
地板
发表于 2018-6-20 13:01:35 | 只看该作者
爆搜
  1. #include <cstdio>

  2. const int N = 110, M = 2510;

  3. struct Edge {
  4.     int v, nex;
  5. }edge[M << 1]; int top, e[N];

  6. inline void add(int x, int y) {
  7.     top++;
  8.     edge[top].v = y;
  9.     edge[top].nex = e[x];
  10.     e[x] = top;
  11.     return;
  12. }

  13. int k, n, ans, cl[N];

  14. void DFS(int x) {
  15.     if(x == n + 1) {
  16.         ans++;
  17.         return;
  18.     }
  19.     for(int i = 1; i <= k; i++) { /// color
  20.         bool f = 1;
  21.         for(int j = e[x]; j; j = edge[j].nex) {
  22.             int y = edge[j].v;
  23.             if(y > x) {
  24.                 continue;
  25.             }
  26.             if(cl[y] == i) {
  27.                 f = 0;
  28.                 break;
  29.             }
  30.         }
  31.         if(f) {
  32.             cl[x] = i;
  33.             DFS(x + 1);
  34.         }
  35.     }
  36.     return;
  37. }

  38. int main() {
  39.     int m;
  40.     scanf("%d%d%d", &n, &m, &k);
  41.     for(int i = 1, x, y; i <= m; i++) {
  42.         scanf("%d%d", &x, &y);
  43.         add(x, y);
  44.         add(y, x);
  45.     }
  46.     DFS(1);
  47.     printf("%d", ans);
  48.     return 0;
  49. }
复制代码
回复 支持 反对

使用道具 举报

0

主题

11

帖子

38

积分

新手上路

Rank: 1

积分
38
5#
发表于 2018-11-4 18:56:28 | 只看该作者

复制代码
回复

使用道具 举报

1

主题

6

帖子

82

积分

注册会员

Rank: 2

积分
82
6#
发表于 2019-10-26 11:39:14 | 只看该作者
链式前向星最好了(逃
  1. //P2819
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. const int maxn=10010;
  5. int n,k,m,ans=0,color[maxn],tot=0,vis[maxn],ver[maxn],nxt[maxn],head[maxn];
  6. inline void add(int x,int y){
  7.         ver[++tot]=y;
  8.         nxt[tot]=head[x];
  9.         head[x]=tot;
  10. }
  11. inline bool valid(int c,int p){
  12.         for(int i=head[p];i;i=nxt[i]){
  13.                 int y=ver[i];
  14.                 if(color[y]==c) return 0;
  15.         }
  16.         return 1;
  17. }
  18. void dfs(int dep){
  19.         if(dep==n+1) return ans++,void();
  20.         for(int i=1;i<=m;++i){
  21.                 if(valid(i,dep)){
  22.                         color[dep]=i;
  23.                         dfs(dep+1);
  24.                         color[dep]=0;
  25.                 }
  26.         }
  27. }
  28. int main(){
  29.         ios::sync_with_stdio(0);
  30.         cin>>n>>k>>m;
  31.         for(int i=1;i<=k;++i){
  32.                 int u,v;
  33.                 cin>>u>>v;
  34.                 add(u,v);
  35.                 add(v,u);
  36.         }
  37.         dfs(1);
  38.         cout<<ans<<endl;
  39.         return 0;
  40. }
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|服务支持:DZ动力|华师一附中OI组  

GMT+8, 2024-12-26 13:34 , Processed in 0.104108 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表