A proper vertex coloring is a labeling of the graph's vertices with colors such that no two vertices sharing the same edge have the same color. A coloring using at most k colors is called a (proper) k-coloring.
Now you are supposed to tell if a given coloring is a proper k-coloring.
Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers N and M (both no more than 104), being the total numbers of vertices and edges, respectively. Then M lines follow, each describes an edge by giving the indices (from 0 to N−1) of the two ends of the edge.
After the graph, a positive integer K (≤ 100) is given, which is the number of colorings you are supposed to check. Then K lines follow, each contains N colors which are represented by non-negative integers in the range of int. The i-th color is the color of the i-th vertex.
Output Specification:
For each coloring, print in a line k-coloring
if it is a proper k
-coloring for some positive k
, or No
if not.
Sample Input:
10 11
8 7
6 8
4 5
8 4
8 1
1 2
1 4
9 8
9 1
1 0
2 4
4
0 1 0 1 4 1 0 1 3 0
0 1 0 1 4 1 0 1 0 0
8 1 0 1 4 1 0 5 3 0
1 2 3 4 5 6 7 8 8 9
Sample Output:
4-coloring
No
6-coloring
No
这题真正的解题思路其实不难,只需要应用一个目前不会的小技巧。难在题目的理解。
对于题目的理解是, 给出边与点的信息,进行染色问题的处理。不难发现,看上去复杂的染色问题,只要掌握一条原则,即相邻两点不能染成同一种颜色,验证给出的颜色序列是否符合这种原则。对于给出序列的思考,可以观察到有10维,不难发现数字代表着每个点的颜色。而边序列代表的信息,则是给出哪两点是相邻的。若相邻两点的颜色相同,则染色失败。
对于颜色的数目,采用一个set集合便可以得出,难便难在超时。一开始的思路是,利用一个二维表存储边的信息,例如 8 7 则将二维表处理为a[8][7]与 a[7][8]均为1,而后难点便是如何确定某个点的相邻点也是同一种颜色。一开始采用的方法是,既然是两个点,便通过两个for循环来处理,使用第二个for循环找出a[i][j]=1的j值,即是与 i 对应的邻接点。显然,当数据量大的时候会超时,参考https://www.liuchuo.net/archives/8025 的方法,建立一个结构取名为edge,用来存储边的信息,edge中有两个int型变量v_1,v_2.分别是两点。这样,当比较颜色时,便可以通过一次for循环通过访问边edge的集合来一次性比较。
代码如下:
#include <bits/stdc++.h>
using namespace std;
struct edge
{
int v_1;
int v_2;
};
int main()
{
int N,M;
cin>>N>>M;//N是点数目 M边数
vector<edge> v(M);
int i,j;
for(i=0;i<M;i++)
{
cin>>v[i].v_1>>v[i].v_2;
}
int K;
cin>>K;
int colors[N]={0};
int flag=0;
while(K--)
{
flag=0;
set <int> color;
for(i=0;i<N;i++)
{
cin>>colors[i];
color.insert(colors[i]);
}
for(i=0;i<M;i++)
{
if(colors[v[i].v_1]==colors[v[i].v_2])
{
flag=1;
break;
}
}
if(flag==1)
{
cout<<"No"<<endl;
}
else if(flag==0)
{
int num=color.size();
cout<<num<<"-coloring"<<endl;
}
color.clear();
}
return 0;
}