問題 C: 【回溯】圖的m着色問題
時間限制: 1 Sec 內存限制: 128 MB提交: 1 解決: 1
[提交][狀態][討論版]
題目描述
給定無向連通圖G=(V, E)和m種不同的顏色,用這些顏色為圖G的各頂點着色,每個頂點着一種顏色。是否有一種着色法使G中相鄰的兩個頂點有不同的顏色?
這個問題是圖的m可着色判定問題。若一個圖最少需要m種顏色才能使圖中每條邊連接的兩個頂點着不同顏色,則稱這個數m為該圖的色數。求一個圖的色數m的問題稱為圖的m可着色優化問題。
編程計算:給定圖G=(V, E)和m種不同的顏色,找出所有不同的着色法和着色總數。
輸入
第一行是頂點的個數n(2≤n≤10),顏色數m(1≤m≤n)。
接下來是頂點之間的相互關系:a b
表示a和b相鄰。當a,b同時為0時表示輸入結束。
輸出
輸出所有的着色方案,表示某個頂點塗某種顏色號,每個數字的后面有一個空格。最后一行是着色方案總數。
樣例輸入
5 4
1 3
1 2
1 4
2 3
2 4
2 5
3 4
4 5
0 0
樣例輸出
1 2 3 4 1
1 2 3 4 3
1 2 4 3 1
1 2 4 3 4
1 3 2 4 1
1 3 2 4 2
1 3 4 2 1
1 3 4 2 4
1 4 2 3 1
1 4 2 3 2
1 4 3 2 1
1 4 3 2 3
2 1 3 4 2
2 1 3 4 3
2 1 4 3 2
2 1 4 3 4
2 3 1 4 1
2 3 1 4 2
2 3 4 1 2
2 3 4 1 4
2 4 1 3 1
2 4 1 3 2
2 4 3 1 2
2 4 3 1 3
3 1 2 4 2
3 1 2 4 3
3 1 4 2 3
3 1 4 2 4
3 2 1 4 1
3 2 1 4 3
3 2 4 1 3
3 2 4 1 4
3 4 1 2 1
3 4 1 2 3
3 4 2 1 2
3 4 2 1 3
4 1 2 3 2
4 1 2 3 4
4 1 3 2 3
4 1 3 2 4
4 2 1 3 1
4 2 1 3 4
4 2 3 1 3
4 2 3 1 4
4 3 1 2 1
4 3 1 2 4
4 3 2 1 2
4 3 2 1 4
Total=48
解題思路:使用回溯法,具體步驟是將cur=1傳入backtrack(),即從第一個開始塗色。
塗的時候從顏色1開始到m,每當塗上一個色,要用ok(cur)判斷第cur個點是否可以塗這個色,不可以的話就不再往下塗了,改試另一個顏色,可以的話就繼續。
當cur>n的時候即前n個點都塗完了,然后輸出結果並cou++計數。
代碼:
#include <iostream> #include <cstdio> using namespace std; int n,m; int a=1,b=1; int cou=0; int graph[20][20]={0}; int color[20]={0}; bool ok(int c){ for(int k=1;k<=n;k++){ if(graph[c][k]&&color[c]==color[k]){ return false; } } return true; } void backtrack(int cur){ if(cur>n){ for(int i=1;i<=n;i++){ printf("%d ",color[i]); } cou++; printf("\n"); }else{ for(int i=1;i<=m;i++){ color[cur]=i; if(ok(cur)){ backtrack(cur+1); } color[cur]=0; } } } int main() { scanf("%d %d",&n,&m); while(scanf("%d %d",&a,&b)!=EOF&&a!=0&&b!=0){ graph[a][b]=1; graph[b][a]=1; } backtrack(1); printf("Total=%d",cou); return 0; }