PAT--1170 Safari Park

A safari park(野生动物园)has K species of animals, and is divided into N regions. The managers hope to spread the animals to all the regions, but not the same animals in the two neighboring regions. Of course, they also realize that this is an NP complete problem, you are not expected to solve it. Instead, they have designed several distribution plans. Your job is to write a program to help them tell if a plan is feasible.

Input Specification:

Each input file contains one test case. For each case, the first line gives 3 integers: N (0<N≤500), the number of regions; R (≥0), the number of neighboring relations, and K (0<K≤N), the number of species of animals. The regions and the species are both indexed from 1 to N.

Then R lines follow, each gives the indices of a pair of neighboring regions, separated by a space.

Finally there is a positive M (≤20) followed by M lines of distribution plans. Each plan gives N indices of species in a line (the i-th index is the animal in the i-th rigion), separated by spaces. It is guaranteed that any pair of neighboring regions must be different, and there is no duplicated neighboring relations.

Output Specification:

For each plan, print in a line Yes if no animals in the two neighboring regions are the same, or No otherwise. However, if the number of species given in a plan is not K, you must print Error: Too many species. or Error: Too few species. according to the case.

Sample Input:

6 8 3
2 1
1 3
4 6
2 5
2 4
5 4
5 6
3 6
5
1 2 3 3 1 2
1 2 3 4 5 6
4 5 6 6 4 5
2 3 4 2 3 4
2 2 2 2 2 2

Sample Output:

Yes
Error: Too many species.
Yes
No
Error: Too few species.

解析:对于每对相邻动物园,我们可以先用map来记录,然后对于每种计划,我们初始化cnt[ ]来记录出现了几种动物,之后N^2直接枚举每一对动物,如果是同一种动物,就查询map判断(i,j)是否出现过,如果出现过则表示在同一个集合中,那么就是No,否则最后输出Yes即可。

注意:记录每一对动物园时,需要双向记录,测试点1就是针对这个点。

#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
const int N=510;
typedef pair<int,int> PII;
map<PII,int> mp;//记录每一对动物园
int k[N],cnt[N];
void solve()
{
	int n,r,m;
	scanf("%d%d%d",&n,&r,&m);
	while(r--)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		mp[{a,b}]=1;//双向记录!
		mp[{b,a}]=1;
	}
	int q;
	scanf("%d",&q);
	while(q--)
	{
		int sum=0;//记录出现过几种动物
		memset(cnt,0,sizeof cnt);
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&k[i]);
			if(++cnt[k[i]]==1) sum++;//种类++
		}
		if(sum<m) printf("Error: Too few species.\n");
		else if(sum>m) printf("Error: Too many species.\n");
		else
		{
			bool flag=true;//是否合法
			for(int i=1;i<=n;i++)
			{
				for(int j=i+1;j<=n;j++)
				{
					if(k[i]==k[j]&&mp[{i,j}])//同种动物在同一集合中,不合法
					{
						flag=false;
						break;
					}
				}
				if(!flag) break;
			}
			if(flag) printf("Yes\n");
			else printf("No\n");
		}
	}
}
int main()
{
	solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值