版权声明:我的GitHub:https://github.com/617076674。真诚求星! https://blog.csdn.net/qq_41231926/article/details/84946134
我的PAT-ADVANCED代码仓:https://github.com/617076674/PAT-ADVANCED
原题链接:https://pintia.cn/problem-sets/994805342720868352/problems/1071785301894295552
题目描述:
题目翻译:
1154 顶点着色
“proper vertex coloring”是用颜色标记图形的顶点,使得共享相同边缘的两个顶点具有不同颜色。使用至多k种颜色的着色称为“k-coloring”。
现在你需要指出给定的着色是否是“k-coloring”。
输入格式:
每个输入文件包含一个测试用例。对于每个测试用例,第一行给出两个正整数N和M(均不超过10 ^ 4),分别代表顶点和边的总数。然后是M行,每行都通过给出边两端的索引(从0到N-1)来描述边。
在描述完边的信息之后,给出一个正整数K(<= 100),这是你需要检查的着色数量。然后紧跟着K行,每行包含N个颜色,这些颜色由int范围内的非负整数表示。第i种颜色表示第i个顶点的颜色。
输出格式:
对每一行查询的颜色信息,如果是“k-coloring”,其中k是一个正整数,则输出“k-coloring”;否则输出“No”。
输入样例:
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
输出样例:
4-coloring
No
6-coloring
No
思路:存储每条边对应的两个节点
对于每一个查询序列,用set集合来去重统计颜色数量。查询每一条边,判断其两个节点对应的颜色是否相同,一旦出现颜色相同的情况就输出“No”。否则,按题目格式输出颜色数量。
时间复杂度是O(KN)。空间复杂度是O(M)。
C++代码:
#include<iostream>
#include<vector>
#include<set>
using namespace std;
struct edge {
int v1, v2;
edge(int _v1, int _v2) {
v1 = _v1;
v2 = _v2;
}
};
int N, M;
vector<edge> edges;
int main() {
scanf("%d %d", &N, &M);
for(int i = 0; i < M; i++) {
int v1, v2;
scanf("%d %d", &v1, &v2);
edges.push_back(edge(v1, v2));
}
int K;
scanf("%d", &K);
for(int i = 0 ; i < K; i++) {
int color[N];
set<int> colorSet;
for(int j = 0; j < N; j++) {
scanf("%d", &color[j]);
colorSet.insert(color[j]);
}
bool flag = true;
for(int j = 0; j < edges.size(); j++) {
if(color[edges[j].v1] == color[edges[j].v2]) {
printf("No\n");
flag = false;
break;
}
}
if(flag) {
printf("%d-coloring\n", colorSet.size());
}
}
return 0;
}
C++解题报告: