给图着色(dfs)

11 篇文章 0 订阅
9 篇文章 0 订阅

【1】求给图着m个色的方案:

#include<bits/stdc++.h>
using namespace std;

//判断k顶点与其所有相邻顶点的着色是否发生冲突
bool OK(int k,int color[105],int graph[105][105])
{
    for (int i = 1; i < k; i++)
    {
        if (graph[k][i] == 1 && color[k] == color[i])
        {
            return false;
        }
    }
    return true;
}

void graphColor(int color[105],int graph[105][105],int n,int m)
{
    int count = 0;  //记录方案数
    int k = 1;  //从1顶点开始搜索
    while (k >= 1)
    {
        color[k] += 1; //着色
        while (color[k] <= m && k <= n)
        {
            if (OK(k, color, graph))
            {
                break;
            }
            else
            {
                color[k] += 1;  //如果发生冲突,则添加一种着色
            }
        }

        if (color[k] <= m && k == n)    //已搜索到最后一一个顶点,输出一个着色组合
        {
            for (int i = 1; i <= k; i++)
            {
                printf("%d ",color[i]);
            }
            printf("\n");
            count += 1;
        }
        else if (color[k] <= m && k < n)        //继续向下搜索
        {
            k += 1;
        }
        else
        {
            color[k] = 0;   //当color[k]>m || k>n时, 回溯
            k -= 1;
        }
    }
    printf("一共有方案数:%d\n",count);
}

int main()
{
    int n,m;
    int color[105];
    int graph[105][105];
    scanf("%d%d",&n,&m);
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            scanf("%d",&graph[i][j]);
        }
    }
    //颜色种类初始化
    for (int i = 1; i <= m; i++)
    {
        color[i] = 0;
    }

    graphColor(color, graph, n, m);
}
/*
5 4
0 1 1 1 0
1 0 1 1 1
1 1 0 1 0
1 1 1 0 1
0 1 0 1 0
*/

在这里插入图片描述

【2】输出最少用几种颜色

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define M 26

int n, ans, color[M];
bool map[M][M], isFind;

bool ok(int x, int c) {   //判断是否存在相邻节点颜色相同
     for (int i = 0; i < n; i++)
        if (map[x][i] && c == color[i])
            return false;
     return true;
}

void DFS(int id, int total) {   //当前搜索到下标为id的节点,此时总共用的色彩数为total
     if (isFind) return;
     if (id >= n) { isFind = true; return; }  //当所有节点都被着色后,返回

     for (int i = 1; i <= total; i++) {
         if (ok(id, i)) {
            color[id] = i;
            DFS(id+1, total);
            color[id] = 0;
         }
     }
     if (!isFind) {    //当用total种颜色无法完成时,则增加一种颜色进行着色
        ans++;
        DFS(id, total+1);
     }
}

int main()
{
    int i, j;
    char s[M];

    while (scanf ("%d", &n) && n) {
          getchar();
          memset (map, false, sizeof (map));
          memset (color, 0, sizeof (color));
          for (i = 0; i < n; i++) {
               gets(s);
               for (j = 2; s[j] != '\0'; j++)
                   map[s[0]-'A'][s[j]-'A'] = true;
          }
          isFind = false;
          ans = 1;
          DFS(0, 1);
          if (ans == 1)
              printf ("1 channel needed.\n");
          else printf ("%d channels needed.\n", ans);
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值