染色问题:先建图。然后给每个顶点涂色,就是把顶点编号改一下。然后针对每个顶点,判断相邻顶点编号是否和当前顶点编号一致,如果一致,说明颜色相同。
方法一:邻接表实现。由于邻接表只能存储终点编号(好像也可以在结构体里存储起始顶点编号,懒得改了),所以还要一个数组存放当前顶点编号。
#include <iostream>
#include <vector>
#include <set>
using namespace std;
const int maxv = 510;
int a[maxv]; //存放顶点的颜色,即动物种类。a[1]=3意为1号顶点颜色编号为3
struct node{
int v; //边终点颜色编号
};
vector<node> G[maxv];
set<int> st;
node no[maxv]; //存放当前顶点颜色编号
int main() {
int n,r,k,m, v1, v2;
scanf("%d%d%d", &n, &r, &k);
for(int i=0; i<r; i++){
scanf("%d%d", &v1, &v2);
G[v1].push_back(node{v2});
G[v2].push_back(node{v1});
}
scanf("%d", &m);
//int v;
for(int i=1; i<=m; i++){
for(int j=1; j<=n; j++){
scanf("%d", &a[j]);
no[j].v = a[j];
st.insert(a[j]);
}
if(st.size()>k) printf("Error: Too many species.\n");
else if(st.size()<k) printf("Error: Too few species.\n");
else{
for(int j=1; j<=n; j++){//给顶点涂色
for(int q=0; q<G[j].size(); q++){
int v = G[j][q].v;
G[j][q].v = a[v];
}
}
bool flag = true;
for(int j=1; j<=n; j++){//判断相邻顶点颜色是否相同
for(int q=0; q<G[j].size(); q++){
v1 = no[j].v;
v2 = G[j][q].v;
if(v1==v2){
flag = false;
break;
}
}
if(flag==false) break;
}
if(flag) printf("Yes\n");
else printf("No\n");
}
st.clear();
}
return 0;
}
方法二:邻接矩阵实现。由于最大顶点只有500个,寻找每个相邻顶点最大复杂度为O(250000),这是可以接受的。G[1][3]=1,第1,3号顶点相邻,要涂色的话只需把1,3改为要涂的颜色即可。假设1号顶点涂5,3号顶点也涂5,只需另创建一个邻接矩阵让G2[5][5]=1即可。然后对G2进行处理。
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
const int maxv = 510;
int G[maxv][maxv], G2[maxv][maxv];
int a[maxv]; //存储每个顶点的颜色
set<int> st;
int main()
{
fill(G[0], G[0]+maxv*maxv, 0);
fill(G2[0], G2[0]+maxv*maxv, 0);
int n,r,k,m, v1, v2;
scanf("%d%d%d", &n, &r, &k);
for(int i=0; i<r; i++){
scanf("%d%d", &v1, &v2);
G[v1][v2] = G[v2][v1] = 1;
}
scanf("%d", &m);
//int v;
for(int i=1; i<=m; i++){
for(int j=1; j<=n; j++){
scanf("%d", &a[j]);
st.insert(a[j]);
}
if(st.size()>k) printf("Error: Too many species.\n");
else if(st.size()<k) printf("Error: Too few species.\n");
else{
bool flag = true;
for(int j=1; j<=n; j++){
for(int q=1; q<=n; q++){
//如果相邻顶点涂色相同
if(G[j][q]==1 && a[j]==a[q]) flag = false;
}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
st.clear();
fill(G2[0], G2[0]+maxv*maxv, 0);
}
return 0;
}