地图着色(回溯法)

一、问题分析

把每一个区域抽象为一个点,把区域相邻用一条边连接,给图上每一点上色,保证该点颜色与相邻点颜色不同,保证颜色的总数最少。给定一个无向图G=(V, E),其中V为顶点集合,E为边集合,图着色问题即为将V分为K个颜色组,每个组形成一个独立集,即其中没有相邻的顶点。其优化版本是希望获得最小的K值。

二、算法选择

在解决这个问题时,回溯法可以用来遍历所有可能的着色方案,并确定最佳的颜色方案。回溯法依据当前已经着色的领域,向剩下的领域分配不同的颜色,如果领域间的相邻关系不符合要求,则撤回刚才的着色方案,并重新分配颜色。一旦找到符合要求的着色方案,则停止搜索,并输出最优解。

三、设计思路

利用回溯法,先从最少的颜色:1,开始向后尝试,无论如何不会超过n种颜色,因位只有n个点,所以就for (1~n)尝试,对于每种颜色从1号点开始染色

对于图G,我们可以使用深度优先搜索(DFS)算法来遍历它。在DFS算法中,我们从一个顶点出发沿着图中的边一直走到不能再往下走为止,然后换另一个顶点继续走,直到遍历完整个图。

求解

邻接表存图

printf("输入点数n, 边数m\n");
    
    cin >> n >> m;
    
    printf("输入%d条无向边, 每行两个整数a,b,表示a和b之间有一条无向边\n\n",m);
    while (m -- ) 
    {
        scanf("%d%d", &a, &b);
        G[a].push_back(b), G[b].push_back(a);
    }

判断函数j

bool dfs(int cur, int k)
{
    if(cur > n)
    {
     printf("染色成功\n\n"); 
     printf("最少需要%d种颜色\n\n", k);
        printf("接下来分别是每个点染上的颜色\n\n");
        for(int i = 1; i <= n; i ++ ) 
        {
      printf("第%d个点的颜色是%d ", i, color[i]);
      if (i % 5 == 0) printf("\n");
  }
  printf("\n\n方案输出完毕");
        printf("\n");
  return true ;
    }
    
    if (!puted[k]) printf("正在尝试能否用%d种颜色为图染色\n", k), puted[k] = true;
    printf("目前正在给点%d染色\n", cur);
    for(int clr = 1; clr <= k; clr ++ )
    {
        color[cur] = clr;
        if(check(cur)) { printf("点%d成功染上第%d钟颜色\n\n", cur, clr); return dfs(cur + 1, k); }
        else printf("对于%d点染第%d种颜色出现冲突\n\n", cur, clr);
        color[cur] = 0;
    }
}

结果展示 

 ​​​​​​​

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值