1. 程式人生 > >【NOJ1575】【演算法實驗二】【回溯演算法】圖的m著色問題

【NOJ1575】【演算法實驗二】【回溯演算法】圖的m著色問題

1575.圖的m著色問題

時限:1000ms 記憶體限制:10000K  總時限:3000ms

描述

給定無向連通圖G和m種不同的顏色。用這些顏色為圖G的各頂點著色,每個頂點著一種顏色。如果有一種著色法使G中每條邊的2個頂點著不同顏色,則稱這個圖是m可著色的。圖的m著色問題是對於給定圖G和m種顏色,找出所有不同的著色法。

輸入

第1行有3個正整數n,r 和m(n < 20,r < 200,m < 10),表示給定的圖G有n個頂點和r條邊,m種顏色。

頂點編號為0,1,2,…,n-1。

接下來的r行中,每行有2個正整數u,v,表示圖G 的一條邊(u,v)。

(僅一組輸入資料)

輸出

輸出不同的著色方案的總數。

//回溯演算法

#include <iostream>

using namespace std;

int n;  //n個頂點
int r;  //r條邊
int m;  //m種顏色
int a[20][20];  //存放邊
int cnt;    //著色方案個數
int color[20];   //存放解方案

void dfs(int k);
bool ok(int k,int i);   //判斷頂點m能否染成第i種顏色

int main()
{
    cin>>n>>r>>m;
    int u,v;
    for(int i=0;i<r;i++){
        cin>>u>>v;
        a[u][v]=1;
        a[v][u]=1;
    }

    dfs(0);

    cout<<cnt<<endl;
    return 0;
}

void dfs(int k) //給第m個頂點上色
{
    if(k==n)
        cnt++;
    else{
        int i;  //第i種顏色
        for(i=1;i<=m;i++){
            color[k]=i;
            if(ok(k,i)) dfs(k+1);
            color[k]=0;
        }
    }
}

bool ok(int k,int i)
{
    for(int j=0;j<k;j++){   //遍歷頂點
        if(a[j][k]==1){     //有邊相連
            if(i==color[j]) //相鄰頂點顏色相同
                return false;
        }
    }
    return true;
}