标签:这就是我 can mrc 表达 div malloc open gtd vol
图着色问题(Graph Coloring Problem, GCP) 又称着色问题,是最著名的NP-完全问题之一。这就是我今天要和大家分析的内容。
通俗易懂的说,就是:有一张图分为N个区域,给你K种颜色,让你为每个区域着色,要求最终满足相邻区域的颜色不相同。
首先,在编程实现里面应该怎么来表达这张有N个区域的图呢?(借用我以前写过的一道作业题,假设有6个区域),我们可以用一个二维数组来存储每个区域两两之间的邻接关系,如下:解释一下就是说,用数组a[6][6]来表示这个6*6的二维数组,那么a[3][4]就表示区域3和区域4的关系,若a[3][4]==1,就证明这两个区域相邻,否则就是不相邻的。
接下来,我们用代码来实现这6个区域的上色问题。(假设给定了4种不同的颜色,也可以用一个一维数组如b[4]来表示哈~~)
1 #include<stdio.h> 2 #include<stdlib.h> 3 #define StackSize 100 4 #define AddSize 10 5 #define COLUMN 6 6 7 typedef struct 8 { 9 int* top; 10 int* base; 11 int stacksize; 12 }Stack; 13 14 int R[COLUMN][COLUMN]; 15 16 void read(int *p); 17 void Initstack(Stack *p);//构建空栈 18 bool judgeColor(Stack *p,int m,int j);//上色法,判断能否用第j种颜色,j<=3; 19 void Push(Stack *p, char j);//第j种颜色入栈 20 void Pop(Stack *p,int *w);//出栈 21 void draw(Stack P);//画图 22 23 void main() 24 { 25 read(R[0]); 26 Stack P; 27 Initstack(&P); 28 int m = 0,j; 29 while (m <= 5) 30 { 31 for (j = 0; j <= 3; j++)//第j种颜色尝试 32 { 33 if (judgeColor(&P,m,j)) 34 { 35 Push(&P, j); 36 break; 37 } 38 } 39 while(j==4)//未能成功上色 40 { 41 --m;//返回上一个区域 42 if (m < 0)//退栈退到第0块区域之前,没区域了,即不能成功为这6个区域上色 43 { 44 printf("NO Solution!"); 45 return; 46 } 47 48 int w;//上一区域颜色 49 Pop(&P, &w);//退栈 50 for (j = w + 1; j <= 3; j++) 51 { 52 if (judgeColor(&P,m,j))//能上此色 53 Push(&P, j); 54 } 55 } 56 m++;//给下一区域上色 57 } 58 printf("OK.\n"); 59 60 for (int t = 0; t < 6; t++) 61 { 62 printf("区域%d上色为%d\n", t, P.base[t]);//指针取下标可以表示数组 63 } 64 65 return; 66 } 67 68 void read(int *p) 69 { 70 FILE * fp = fopen("../relation_table.txt", "r"); 71 if (!fp) exit; 72 for (int i=0;i<6;i++) 73 { 74 for (int j = 0; j < 6; j++) 75 { 76 fscanf(fp, "%d", p++); 77 } 78 } 79 fclose(fp); 80 } 81 82 void Initstack(Stack *p)//构建空栈 83 { 84 p->base= (int *)malloc(sizeof(int)*StackSize); 85 if (!p->base) exit; 86 p->top = p->base; 87 p->stacksize = StackSize; 88 return; 89 } 90 91 void Push(Stack *p, char j)//第j种颜色入栈 92 { 93 if (p->top - p->base == p->stacksize)//栈满 94 { 95 p->base = (int *)realloc(p->base,( p->stacksize + AddSize)*sizeof(int)); 96 if (!p->base) exit; 97 p->top = p->base + p->stacksize; 98 p->stacksize += AddSize; 99 } 100 *(p->top++) = j; 101 return; 102 } 103 104 void Pop(Stack *p, int *w)//出栈 105 { 106 if (p->base == p->top) exit; 107 *w = *(--p->top); 108 return; 109 } 110 111 bool judgeColor(Stack * P,int m,int j)//判断第m个区域能否用第j种颜色 112 { 113 for (int i=0; i<m&&m>0; i++) 114 { 115 if (R[i][m] == 1)//第i个区域与m区域相邻 116 { 117 if (*(P->base + i) == j)//j颜色被用过了 118 return false; 119 } 120 } 121 return true; 122 }
我们来看看最终的结果,见证奇迹的时刻到了!
当然,你也可以修改上面的参数,来解决更多区域更多颜色的上色问题!
标签:这就是我 can mrc 表达 div malloc open gtd vol
原文地址:http://www.cnblogs.com/to-sunshine/p/5987976.html