PAT甲级1154 Vertex Coloring (零基础都能看懂)

1154 Vertex Coloring (25分)
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 10​4​​), 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.

题目翻译:

1154 顶点着色

“proper vertex coloring”是用颜色标记图形的顶点,使得共享相同边缘的两个顶点具有不同颜色。使用至多k种颜色的着色称为“k-coloring”。

现在你需要指出给定的着色是否是“k-coloring”。

输入格式:

每个输入文件包含一个测试用例。对于每个测试用例,第一行给出两个正整数N和M(均不超过10 ^ 4),分别代表顶点和边的总数。然后是M行,每行都通过给出边两端的索引(从0到N-1)来描述边。

在描述完边的信息之后,给出一个正整数K(<= 100),这是你需要检查的着色数量。然后紧跟着K行,每行包含N个颜色,这些颜色由int范围内的非负整数表示。第i种颜色表示第i个顶点的颜色。

Sample Input:
10 11 //N个顶点,M条边
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

题目解析:
我觉得此题看懂题干就是一个难点,我个渣渣结合翻译软件还看了好长时间才明白(555555…)
看懂以后要想清楚用哪些数据结构存储数据。因为这题里又有边又有点。
1.刚开始边的个数未知,可以用变长数组vector存储.
2.每个点的颜色,由于要统计“几着色问题(颜色个数)”,所以可以用set存储颜色(set可以去重并且元素递增)
最后枚举边,看边的顶点颜色是否一致,如果一致则不是n着色问题。

代码展示:

#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
using namespace std;
struct node
{
	int p1,p2;
};
int main()
{
	int m,n,k; 
	cin>>m>>n;//m个点,n条边 
	vector<node> bian(n);//必须初始化并且必须用圆括号 
	for(int i=0;i<n;i++)
	{
		scanf("%d %d",&bian[i].p1,&bian[i].p2);//scanf读入时间比cin读入时间短 
	}
	cin>>k;
	while(k>0)
	{
		int dian[10000]={0};//数组初始化很重要,存储点的颜色,并且题目要求边不大于10000
		set<int> s;
		bool flag=true;
		for(int j=0;j<m;j++)
		{
			scanf("%d",&dian[j]);
			s.insert(dian[j]);
		}
		for(int q=0;q<n;q++)//枚举n条边 
		{
			if(dian[bian[q].p1]==dian[bian[q].p2])
			{
				flag=false;
				break;
			}		
		}
		if(flag==false)
		{
			cout<<"No"<<endl;
		}
		else
		{
			cout<<s.size()<<"-coloring"<<endl;
		}
		k--;
	}
}

总结
写这道题可真是累死我了,心态爆炸了。
出现几个问题
1.存储点的颜色数组大小必须看题目要求不大于10000,否则发生段错误。
2.vector是变长数组,此题需要以数组的方式读入,需要初始化。初始化必须用圆括号。不是方括号。否则出错。
3.scanf读入时间比cin读入时间短

加油吧,继续干。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值