[SOJ1039]Phone Home(深搜,染色问题)
題目如下:
染色問題就是說,離散的點(diǎn)之間,如果有關(guān)聯(lián)的點(diǎn),這個(gè)兩個(gè)點(diǎn)就不能是同樣的顏色
然后回答最少用多少種顏色。
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.
實(shí)現(xiàn)代碼如下(附有講解,那個(gè)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間有通路,就是在說這兩不應(yīng)該是一樣的void DFS(int now) { //now表示的是當(dāng)前點(diǎn)的位置//關(guān)于點(diǎn)的編號進(jìn)行迭代 //邊界條件還沒有處理好if (now >= n)return;// 設(shè)置邊界判斷,這個(gè)只是為了增加函數(shù)的健壯性而添加的if (now == 0){ans = 1;color[0] = 1; // 將第一個(gè)設(shè)置好} // 起始條件,當(dāng)這個(gè)點(diǎn)是起始點(diǎn)的時(shí)候if (now < n - 1){ //說明你可以選下一個(gè)的情況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個(gè)點(diǎn)和第now+1個(gè)值相連,并且第i個(gè)點(diǎn)沒有著色canChooseColor[color[i]] = true; //這里,如果是true意味著這個(gè)點(diǎn)不能選了}}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; // 深搜回溯}}//再新建一個(gè)顏色著色if (ans <= n){ans++;color[now + 1] = ans;DFS(now + 1);ans--;}}else if (ans < final_ans){final_ans = ans;}//這樣,就只需要在邊界條件上考慮下那個(gè)最大或者是最小的問題 }int main() {int caseNum = 1;while (cin >> n && n){ // 確保是n個(gè)點(diǎ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));} // 存儲點(diǎn)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;}}}// 存儲好了兩點(diǎn)間的關(guān)系存在,正確final_ans = 1 << 30;DFS(0); //從0編號的點(diǎn)開始遍歷cout << "The towers in case " << caseNum++ << " can be covered in " << final_ans << " frequencies.\n";} }總結(jié)
以上是生活随笔為你收集整理的[SOJ1039]Phone Home(深搜,染色问题)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 猫狗收养所问题(指针模拟)
- 下一篇: 全排列的生成