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");
- }
- }
留言
張貼留言