地图着色问题

  • 设计任务与目标

 

1、问题描述

图着色问题(Graph Coloring Problem, GCP) 又称着色问题,是最著名的NP-完全问题之一。道路着色问题(Road Coloring Problem)是图论中最著名的猜想之一。给定一个无向图G=(V, E),其中V为顶点集合,E为边集合,图着色问题即为将V分为K个颜色组,每个组形成一个独立集,即其中没有相邻的顶点。其优化版本是希望获得最小的K值。

2、设计目标

给定任意无向图,求出该图最少的着色数并给出着色方案。

  • 设计思路

3、问题分析

地图着色问题是一个抽象的图形学问题,用程序实现对各个区域进行着色,并且相邻省所用的颜色不同,同时保证颜色的总数最少,那么就是如何将这些抽象的进行数据化。如何将程序所需要的功能模拟着色在计算机中编程实现。

由地图着色问题很容易想到图的着色问题,因此可以把地图抽象为无向图来解决地图的着色问题。其本质是图着色问题(Graph ColoringProblem, GCP) 又称着色问题,是最著名的NP完全问题之一。 对地图的抽象相当于对图的抽象,即以邻接矩阵来实现地图的区域相邻的描绘,而对地图的区域数即以图的顶点数来描绘。具体是将各个区域进行编号,然后利用无向图各个顶点之间的边来表示各省的相邻关系。地图着色问题与著名四色定理:四色定理是一个著名的数学定理:如果在平面上划出一些邻接的有限区域,那么可以用四种颜色来给这些区域染色,使得每两个邻接区域染的颜色都不一样:另一个通俗简洁的说法是:每个地图都可以用不多于四种颜色来染色,而且不会有两个邻接的区域颜色相同。这就是著名的四色定理,由四色定理可以想到只需要四种颜色就可以为一个区域的地图着上颜色,而且相邻区域的颜色不相同。

 

4、图的m-着色优化问题

若一个图最少需要m种颜色才能使图中任意相邻的2个顶点着不同颜色,则称这个数m为该图的色数。求一个图的最小色数m的问题称为m-着色优化问题。

1步骤

计算机中,图主要可以用两种方法表示:邻接矩阵和邻接链表。N个顶点的邻接矩阵是一个N*N的布尔矩阵,图中的每一个顶点都由一行或者一列来表示,如果从第i个顶点和第j个顶点之间有边连接,则矩阵第i行,第j列的元素等于1,如果没有边连接,则等于0.这就是图的邻接矩阵表示。
    那么地图也可以抽象为一个图,其可以用邻接矩阵来进行模拟:对于每一个地图,我们可以把每一个区(区域或国家)看作一个点,而区与区之间的邻接关系看作点与点之间的连线。从而将地图抽象为-个图,然后就可以用邻接矩阵抽象。

(2)输出代码

 

#include <iostream>

#include <bits/stdc++.h>

using namespace std;

 

#define MAX 100

int m=1;

int graph[MAX][MAX]; //点与点之间的联系

int color[MAX]; //每个点的颜色

 

void BackTrack(int n)

{

    color[1]=1; //第一个点先染色

    for(int t=2; t<=n; t++) //从第二个点开始染色

    {

        int f=0;  //假设t点与染色点都有联系

        for(int j=1; j<t; j++)//t点之前的都已经染色,查找t点与染色点是否有联系

        {

            if(graph[t][j]!=1)  //有个点与t点无联系

            {

                f=1;  //假设失败

                color[t]=color[j];  //无联系则颜色可以相同

                break;

            }

        }

        if(f==0)  //假设成功

        {

            color[t]=m+1;  //都有联系只能染新颜色

            m++;

        }

    }

    for(int i=1;i<=n;i++)//输出各点颜色

    {

        cout<<color[i]<<" ";

    }

    cout<<endl;

}

int main()

{

    int n;  //n个点

    cin>>n;

 

    //构建图G

    int i,j;

    while(scanf("%d%d",&i,&j) && (i!=0 || j!=0)) //点与点之间的联系

    {

        graph[i][j]=1;

        graph[j][i]=1;

    }

    BackTrack(n);

    cout<<m; //最少颜色数

    return 0;

}

 

(3)输出结果

 
  

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值