10004 Bicoloring
題目原文
題目說明
只有兩種顏色,且相鄰兩點需不同色,若可以達成,則輸出 BICOLORABLE,反之輸出 NOT BICOLORABLE。
思路
首先以 vector 建立表格來儲存與某節點相鄰的其他節點,以 queue 來儲存節點走訪的順序。
建立好連通表後,開始走訪,走訪做兩種事情:著色和檢查是否同色,可隨機從某點開始(以下程式碼以 n1 當第一個節點),將其 push 進 queue 裡並著上顏色,塗完顏色後以 current 記住後 pop 出去,
接著開始替相鄰節點(由連通表依序取出)著色,若相鄰節點尚未著色,則 push 到 queue 裡,當作下一個要走訪的 current,並著上與當前 current 相反顏色;已著色則檢查是否與當前 current 同色,同色則可確定非 bicolorable。著完後色都沒問題即為 bicolorable。
簡言之,
1. 建連通表 2. 按連通表依序著色 3. 著色過程中檢查是否符合規定。
題目說明
只有兩種顏色,且相鄰兩點需不同色,若可以達成,則輸出 BICOLORABLE,反之輸出 NOT BICOLORABLE。
思路
首先以 vector 建立表格來儲存與某節點相鄰的其他節點,以 queue 來儲存節點走訪的順序。
建立好連通表後,開始走訪,走訪做兩種事情:著色和檢查是否同色,可隨機從某點開始(以下程式碼以 n1 當第一個節點),將其 push 進 queue 裡並著上顏色,塗完顏色後以 current 記住後 pop 出去,
接著開始替相鄰節點(由連通表依序取出)著色,若相鄰節點尚未著色,則 push 到 queue 裡,當作下一個要走訪的 current,並著上與當前 current 相反顏色;已著色則檢查是否與當前 current 同色,同色則可確定非 bicolorable。著完後色都沒問題即為 bicolorable。
簡言之,
1. 建連通表 2. 按連通表依序著色 3. 著色過程中檢查是否符合規定。
#include<cstdio> #include<vector> #include<queue> int main() { int node; while(scanf("%d", &node) && node) { int edge, n1, n2; int color[200] = {0}; bool check = true; std::vector<int> vec[205]; // 所在列數代表它是第幾個點 後面push進和它連接的點 std::queue<int> que; scanf("%d", &edge); for(int i = 0; i < edge; i++) { scanf("%d %d", &n1, &n2); vec[n1].push_back(n2); // 建連通表 記得兩邊互相連接 vec[n2].push_back(n1); } que.push(n1); color[n1] = 1; while(!que.empty() && check) // 開始走訪 { int current = que.front(); // 先用current存起來 que.pop(); for(int i = 0; i < vec[current].size(); i++) { int j = vec[current][i]; if(color[j] == 0) // 還沒上過色 { que.push(j); color[j] = -color[current]; } else if(color[j] == color[current]) { check = false; break; } } } if(check) printf("BICOLORABLE.\n"); else printf("NOT BICOLORABLE.\n"); } }
留言
張貼留言