L2-023 圖着色問題 (25 分)
圖着色問題是一個著名的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<vector>
#include<set>
using namespace std;
struct Point {
int color, visited;
vector<int> road;
}point[501];
int v, e, k, a, b, n;
bool judge() {
set<int> colors;
for (int i = 1; i <= v; i++) //檢查顏色是否有k種
colors.insert(point[i].color);
if (colors.size() != k)
return false;
for (int i = 1; i <= v; i++) //對於每個點,檢查它與相鄰點是否顏色相同
for (auto& it : point[i].road)
if (point[it].color == point[i].color)
return false;
return true;
}
int main() {
scanf("%d%d%d", &v, &e, &k);
for (int i = 0; i < e; i++) {
scanf("%d%d", &a, &b);
point[a].road.push_back(b);
point[b].road.push_back(a);
}
scanf("%d", &n);
for (int i = 0; i < n; i++) {
for (int j = 1; j <= v; j++)
scanf("%d", &point[j].color);
printf("%s\n", (judge() ? "Yes" : "No"));
}
return 0;
}