團體天梯 L2-023 圖着色問題 (25 分)(結構優化)

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章