L2-023 图着色问题

传送门

题目描述

在一张无向图\(V\)中,用指定的\(k\)种颜色为其中的点上色,但是要求不能让相邻的两个点有同样的颜色,当然,本题不是让你生成可行方案,而是给出方案,让你判断这是否是可行方案

输入说明

第一行给出三个正整数 \(V,E,K\) , 分别表示图的顶点数,边数,颜色数。随后E行,每行给出两个相邻的点。接着给出一个正整数N,随后给出N个涂色方案。

输出说明

如果该方案可行,输出Yes ,否则输出No

解题思路

需要建图,其实很多题目建图,无论是邻接表还是邻接矩阵都是可以的,尤其是像天梯赛这样数据很小的题目,但是本题就是一个很好的例外,这道题要用邻接矩阵,因为这道题没有 邻接表的核心特质 ,邻接表的核心特质为“需要通过某个节点去访问与他有关系的所有节点” ,而邻接矩阵主要是直接访问两个点之间的关系。

我们用e[510][510]来记录边关系,再用个数组c[510]来记录点的颜色,然后对于每一种方案,直接暴力个双重循环(这里的逻辑非常简单),还要补充一点,就是如果我们只进行这一步,会WA,因为题目要求用\(K\)种颜色,如果给出的颜色不够\(K\)个,不符题意,按理来说也要输出No,所以我们还需要另外统计颜色的数量(显然又要用表来计数)。

CE1DB43BB7F0DAFE94271DD9B2F0007A
这种题目已经是小菜一碟了

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
bool e[510][510];
int c[510];
int cnt[510];
int main()
{
	int v,E,k;
	cin>>v>>E>>k;
	while(E--)
	{
		int r,l;cin>>r>>l;
		e[r][l] = 1;
		e[l][r] = 1;
	}

	int t;cin>>t;
	while(t--)
	{
		memset(c,0,sizeof c);
		memset(cnt,0,sizeof cnt);
		bool suc = true;
		int times = 0;
		for(int i = 1 ; i <= v ; i++) 
		{
			cin>>c[i];
			cnt[c[i]]++;
			if(cnt[c[i]] == 1) times++;	
			
		}
//		cout<<times<<endl;
		if(times != k) suc = false;
		
		if(!suc)
		{
			cout<<"No"<<endl;
			continue;
		}
		
		for(int i = 1 ; i <= v ; i++)
		{
			for(int j = 1 ; j < i ; j++)
			{
				if(e[i][j] && c[i] == c[j]) suc = false;
				if(!suc) break;
			}
			if(!suc) break;
		}
		if(suc) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
	return 0;
}
posted @ 2026-03-15 19:50  shuiwangrenjia  阅读(1)  评论(0)    收藏  举报