圖着色問題是一個著名的NP完全問題。給定無向圖G=(V,E),問可否用K種顏色為V中的每一個頂點分配一種顏色,使得不會有兩個相鄰頂點具有同一種顏色?
但本題並不是要你解決這個着色問題,而是對給定的一種顏色分配,請你判斷這是否是圖着色問題的一個解。
輸入格式:
輸入在第一行給出3個整數V(0<V≤500)、E(≥0)和K(0<K≤V),分別是無向圖的頂點數、邊數、以及顏色數。頂點和顏色都從1到V編號。隨后E行,每行給出一條邊的兩個端點的編號。在圖的信息給出之后,給出了一個正整數N(≤20),是待檢查的顏色分配方案的個數。隨后N行,每行順次給出V個頂點的顏色(第i個數字表示第i個頂點的顏色),數字間以空格分隔。題目保證給定的無向圖是合法的(即不存在自回路和重邊)。
輸出格式:
對每種顏色分配方案,如果是圖着色問題的一個解則輸出Yes
,否則輸出No
,每句占一行。
輸入樣例:
6 8 3 2 1 1 3 4 6 2 5 2 4 5 4 5 6 3 6 4 1 2 3 3 1 2 4 5 6 6 4 5 1 2 3 4 5 6 2 3 4 2 3 4
輸出樣例:
Yes
Yes
No
No
#include<iostream> #include<string> #include<vector> #include<set> using namespace std; vector<vector<int>>G(501); int color[501] = { 0 }; bool check(int V) { for (int i = 1; i <= V; i++) for (int j = 0; j < G[i].size(); j++) if (color[i] == color[G[i][j]]) return false; return true; } int main() { int V, E, K, N; cin >> V >> E >> K; for (int i = 0; i < E; i++) { int start, end; cin >> start >> end; G[start].push_back(end); G[end].push_back(start); } cin >> N; for (int i = 0; i < N; i++) { set<int>color_kind; for (int j = 1; j <=V; j++) { cin >> color[j]; color_kind.insert(color[j]); } if (check(V) && color_kind.size() == K) cout << "Yes" << endl; else cout << "No" << endl; } return 0; }