[SOJ1039]Phone Home(深搜,染色问题)
題目如下:
染色問題就是說,離散的點之間,如果有關聯的點,這個兩個點就不能是同樣的顏色
然后回答最少用多少種顏色。
Input
There will be multiple test cases. Input for each test case will consist of two lines: the first line will contain the integer n, indicating the number of towers. The next line will be of the form x1 y1 x2 y2 … xn yn where xi yi are the coordinates of tower i. A pair of towers are considered “near” each other if the distance between them is no more than 20. There will be no more than 12 towers and no tower will have more than 4 towers near it. A value of n = 0 indicates end of input.
Output
For each test case, you should print one line in the format:
The towers in case n can be covered in f frequencies.
where you determine the value for f. The case numbers, n, will start at 1.
Sample Input
5
0 0 5 7.5 1 -3 10.75 -20.1 12.01 -22
6
0 1 19 0 38 1 38 21 19 22 0 21
0
Sample Output
The towers in case 1 can be covered in 3 frequencies.
The towers in case 2 can be covered in 2 frequencies.
實現代碼如下(附有講解,那個node也可以換成pair來做)
#include <iostream> #include <vector> #include <cmath> #include <cstring> using namespace std; struct Node {double first, second;Node(double f = -1, double s = -1) : first(f), second(s) {}; }; double Distance(Node p, Node q) {return sqrt((p.first - q.first) * (p.first - q.first) + (p.second - q.second) * (p.second - q.second)); }int ans = 0, n, final_ans = 1 << 30; int color[14]; // 在color中0表示無顏色 vector<Node> v; bool array_[14][14]; // 地圖,array[i][j] == true,表示i,j間有通路,就是在說這兩不應該是一樣的void DFS(int now) { //now表示的是當前點的位置//關于點的編號進行迭代 //邊界條件還沒有處理好if (now >= n)return;// 設置邊界判斷,這個只是為了增加函數的健壯性而添加的if (now == 0){ans = 1;color[0] = 1; // 將第一個設置好} // 起始條件,當這個點是起始點的時候if (now < n - 1){ //說明你可以選下一個的情況bool canChooseColor[14];memset(canChooseColor, false, sizeof(canChooseColor)); //可選色表的初始化for (int i = 0; i < v.size(); ++i){if (array_[i][now + 1] && color[i] != 0){ // 第i個點和第now+1個值相連,并且第i個點沒有著色canChooseColor[color[i]] = true; //這里,如果是true意味著這個點不能選了}}bool flag = false;for (int i = 1; i <= ans; ++i){if (!canChooseColor[i]){ //用可以著色的已有的顏色著色color[now + 1] = i;DFS(now + 1);flag = true;color[now + 1] = 0; // 深搜回溯}}//再新建一個顏色著色if (ans <= n){ans++;color[now + 1] = ans;DFS(now + 1);ans--;}}else if (ans < final_ans){final_ans = ans;}//這樣,就只需要在邊界條件上考慮下那個最大或者是最小的問題 }int main() {int caseNum = 1;while (cin >> n && n){ // 確保是n個點v.clear();memset(color, 0, sizeof(color));double x, y;for (int i = 0; i < n; ++i){cin >> x >> y;v.push_back(Node(x, y));} // 存儲點memset(array_, false, sizeof(array_));for (int i = 0; i < v.size(); ++i){for (int j = i + 1; j < v.size(); ++j){if (Distance(v[i], v[j]) - 20 < 1e-6){array_[i][j] = array_[j][i] = true;}}}// 存儲好了兩點間的關系存在,正確final_ans = 1 << 30;DFS(0); //從0編號的點開始遍歷cout << "The towers in case " << caseNum++ << " can be covered in " << final_ans << " frequencies.\n";} }總結
以上是生活随笔為你收集整理的[SOJ1039]Phone Home(深搜,染色问题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 猫狗收养所问题(指针模拟)
- 下一篇: 全排列的生成