//dfs染色+二分答案 #include<cstdio> #include<iostream> #include<cstring> #include<vector> using namespace std; const double MAX = 400; struct coord { double x,y; }P[15]; double calDis(coord a,coord b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } vector<int> E[15]; int G[15];//G是染色情况 int ans,mid,N; int Case; void dfs(int x,int fa,int k) { G[x] = k;//染第K种颜色 for(int i = 0;i < E[x].size();++i) { int y = E[x][i]; if(y == fa) continue; if(G[x] == G[y])//如果两座塔颜色一样 { G[x] = 0;//修改为0,然后立即返回,即回溯,修改递归函数出口 return; } }//上面这一步骤是检查周围和他相连的塔有没有出现颜色冲突 for(int i = 0;i < E[x].size();++i) { int y = E[x][i]; if(y == fa) continue; for(int j = 1;j <= mid;++j)//mid是二分出来的答案 { if(G[y] == 0 && j != k) dfs(y,x,j);//下一个点没有染过色,切保证颜色和爸爸的颜色不同 } } } bool solve(int res) { for(int i = 1;i <= N;++i) if(!G[i]) dfs(i,0,1); for(int i = 1;i <= N;++i) if(!G[i]) return false;//如果有的点未能成功染色,则返回染色失败 return true; } int main() { while(scanf("%d",&N) && N) { memset(E,0,sizeof(E)); for(int i = 1;i <= N;++i) scanf("%lf%lf",&P[i].x,&P[i].y); for(int i = 1;i <= N;++i) for(int j = i+1;j <= N;++j) if(calDis(P[i],P[j]) <= MAX) { E[i].push_back(j); E[j].push_back(i); }//构图,感觉用邻接矩阵就好了,没必要出动邻接表,自找麻烦 int l = 1,r = N; while(l <= r)//二分答案过程 { mid = (l+r) >> 1;//假设答案是MID,即假设用MID种颜色来染,看能不能成功 memset(G,0,sizeof(G));//每次都要清空染色情况 if(solve(mid)) { ans = mid; r = mid - 1; } else l = mid + 1; } printf("The towers in case %d can be covered in %d frequencies./n",++Case,ans); } }