1. 程式人生 > >演算法之圖的m著色問題

演算法之圖的m著色問題

問題描述:給定無向連通圖G和m種不同的顏色。用這些顏色為圖G的各頂點著色,每個頂點著一種顏色。求解一種著色法,使得G中每條邊上的2個頂點著色不同。

若一個圖最少需要m種顏色才能使圖中每2條邊連線的2個頂點著色不同,則稱這個數m為該圖的色數。求一個圖的色數的問題稱為圖的m可著色優化問題。

給定圖G=(V,E)和m種顏色,如果該圖是m可著色的,找出所有不同的著色方案。

問題分析:分析可知,該問題的解空間樹是一棵完全m叉樹,每一層中的每一結點都有m個兒子(即m種不同的著色方案)。

定義陣列x[n]儲存可行解,二維陣列中元素a[i][j]表示頂點i和j是否連通(1連通0不連通)。

#include <iostream>
using namespace std;

int N=5,    //頂點個數
    M=4;    //顏色種類
int sum=0;  //可行解數量
int x[5]={-1,-1,-1,-1,-1};  //記錄可行解
int a[5][5]={       //各頂點之間的連線關係
    /*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*/
    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
};

bool Ok(int k)  //判斷是否滿足條件(剪枝函式)
{
    for(int i=0;i<N;i++)
    {
        if(a[k][i]==1&&x[k]==x[i]&&x[i]!=-1)return false;
    }
    return true;
}

void Backtrack(int t)
{
    if(t>=N)    //到達葉子結點,記錄一個可行解
    {
        sum++;
        for(int i=0;i<N;i++)
            cout<<x[i]+1<<" ";
        cout<<endl;
    }
    else
    {
        for(int i=0;i<M;i++)
        {
            x[t]=i;
            if(Ok(t))Backtrack(t+1);
            x[t]=-1;
        }
    }
}



int main()
{
    Backtrack(0);
    cout<<sum<<endl;
}

時間複雜度:O(m*n^2)