染色问题初探。
问题就是模拟蜂窝染色。
方法一,对每个点,扫描周围相邻的每一个点,从1(颜色)开始,有重复则递增,会找到染本点的最小数字。
问题就是模拟蜂窝染色。
方法一,对每个点,扫描周围相邻的每一个点,从1(颜色)开始,有重复则递增,会找到染本点的最小数字。
所有点中最大的数即为总共需要的颜色数。O(n^2)的·复杂度。
// 居然AC了...说明测试数据的局限性!!!.
// 这个方法后来举个反例证明是错误的,如果按照度数由大到小的顺序搜索呢?也不知道对不对。
后来发现好像对着呢,,,把当初的疑惑注释掉....一下就是举得例子,发现当时算错了,也不能推翻我的算法
#include<stdio.h>
#include<cmath>
#include<cstring>
const double eps = 1e-8;
double x[12], y[12];
int map[12][12];
int n, tot;
int color[12];
inline double dis(double x0, double y0, double x1, double y1){
return sqrt( (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
}
void dfs(int k){
if(!color[k]){
int i , j, tc = 1;
bool flg = 1;
while(flg){
flg = 0;
for(i = 0; i < n; i++) if(map[k][i]){
if(tc == color[i]){
tc++; flg = 1;
break;
}
}
}
color[k] = tc;
}
}
int main(){
//freopen("in.txt", "r", stdin);
int cas = 0;
while(scanf("%d" , &n)!=EOF && n){
cas++;
int i, j;
for(i = 0; i < n; i++ )scanf("%lf%lf", x + i, y + i);
memset(map, 0, sizeof(map));
memset(color, 0, sizeof(color));
for(i = 0; i < n; i++){
for(j = 0; j < n; j++)if(i != j){
if( dis(x[i], y[i], x[j], y[j]) <= 20 + eps)map[i][j] = 1;
}
}
tot = 0;
for(i = 0; i < n; i++){
dfs(i);
if(color[i] > tot)tot = color[i];
}
printf("The towers in case %d can be covered in %d frequencies.\n", cas, tot);
}
}
正规解法是深搜,我加了注释。是lh 写的,有点难懂
#include <stdio.h>
#include <math.h>
const double eps = 1e-6;
typedef struct
{
double x, y;
}POINT;
POINT tower[12];
int graph[12][12];
int color[12];
int n;
double dist(POINT a, POINT b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int search(int dep, int num)//num种颜色可以成功么?
{
int i, j;
if (dep == n) return 1;
for (i=0; i<num; i++)//dep 染 i 可以么?
{ //当前只染到dep
for (j=0; j<dep; j++) if (graph[dep][j] && color[j] == i) break;
if (j < dep) continue;
//以上2句:若果当前dep不能染 i ,继续i++。如果可以,则j>=dep,执行以下
color[dep] = i;
if (search(dep + 1, num)) return 1;
}
return 0;
}
int main()
{
int cn, i, j;
cn = 1;
while (scanf("%d", &n), n > 0)
{
for (i=0; i<n; i++) scanf("%lf%lf", &tower[i].x, &tower[i].y);
for (i=0; i<n; i++)
for (j=0; j<n; j++)
if (i != j && dist(tower[i], tower[j]) <= 20 + eps) graph[i][j] = 1; else graph[i][j] = 0;
for (i=1; i<=5; i++)
{
color[0] = 0;
if (search(1, i)) break;
}
printf("The towers in case %d can be covered in %d frequencies.\n", cn, i);
cn ++;
}
return 0;
}