【題解】圖的m着色問題


題目背景

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

 

題目描述

  對於給定的無向連通圖G和m種不同的顏色,編程計算圖的所有不同的着色法。

 

輸入格式

  第1行有3個正整數n,k 和m,表示給定的圖G有n個頂點和k條邊,m種顏色。頂點編號為1,2,…,n。接下來的k行中,每行有2個正整數u,v,表示圖G 的一條邊(u,v)。

 

輸出格式

   程序運行結束時,將計算出的不同的着色方案數輸出。

 

輸入樣例

5 8 4

1 2

1 3

1 4

2 3

2 4

2 5

3 4

4 5

 

輸出樣例

48

 

說明

  n<=100;k<=2500;

  在n很大時保證k足夠大。

  保證答案不超過20000。

 

題解

  別的剪枝不多說了。在這一題中,我們要搜索的起點其實只用搜一種顏色,最后輸出的時候再乘上$m$即可(乘法原理)。

#include <iostream>

#define MAX_N (100 + 5)
#define MAX_K (2500 + 5)
#define MAX_M (2500 + 5)

using namespace std;

struct Edge
{
    int to;
    int next;
};

int n, k, m;
int h[MAX_N], tot;
Edge e[MAX_K + MAX_K];
int c[MAX_N][MAX_M];
int ans;

inline void Add_Edge(int u, int v)
{
    e[++tot].to = v;
    e[tot].next = h[u];
    h[u] = tot;
    return;
}

void DFS(int u)
{
    if(u > n)
    {
        ++ans;
        return;
    }
    for(register int i = 1; i <= m; ++i)
    {
        if(c[u][i]) continue;
        for(register int j = h[u]; j; j = e[j].next)
        {
            ++c[e[j].to][i]; 
        }
        DFS(u + 1);
        for(register int j = h[u]; j; j = e[j].next)
        {
            --c[e[j].to][i]; 
        }
    }
    return;
}

int main()
{
    cin >> n >> k >> m;
    int u, v; 
    for(register int i = 1; i <= k; ++i)
    {
        cin >> u >> v;
        Add_Edge(u, v);
        Add_Edge(v, u);    
    }
    for(register int i = h[1]; i; i = e[i].next)
    {
        ++c[e[i].to][1];
    }
    DFS(2);
    cout << ans * m;
    return 0;
} 
參考程序

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM