ZOJ 3601Unrequited Love

Unrequited Love

Time Limit: 16 Seconds       Memory Limit: 131072 KB

There are n single boys and m single girls. Each of them may love none, one or several of other people unrequitedly and one-sidedly. For the coming q days, each night some of them will come together to hold a single party. In the party, if someone loves all the others, but is not loved by anyone, then he/she is called king/queen of unrequited love.

Input

There are multiple test cases. The first line of the input is an integer T ≈ 50 indicating the number of test cases.

Each test case starts with three positive integers no more than 30000 -- n m q. Then each of the next n lines describes a boy, and each of the next m lines describes a girl. Each line consists of the name, the number of unrequitedly loved people, and the list of these people's names. Each of the last q lines describes a single party. It consists of the number of people who attend this party and their names. All people have different names whose lengths are no more than 20. But there are no restrictions that all of them are heterosexuals.

Output

For each query, print the number of kings/queens of unrequited love, followed by their names in lexicographical order, separated by a space. Print an empty line after each test case. See sample for more details.

Sample Input

2
2 1 4
BoyA 1 GirlC
BoyB 1 GirlC
GirlC 1 BoyA
2 BoyA BoyB
2 BoyA GirlC
2 BoyB GirlC
3 BoyA BoyB GirlC
2 2 2
H 2 O S
He 0
O 1 H
S 1 H
3 H O S
4 H He O S

Sample Output

0
0
1 BoyB
0

0
0

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3601

ps:寒假集训训练赛的题目,百度翻译太可怕了,把“不保证每个人都是异性恋”翻译成了“保证每个人都是异性恋”,刚好没注意到这句话的英文,幸好方法里不涉及这一点,令人窒息,英语真是个让人头大的语言。

题意:给t组测试数据,每组第一行给出男生数量,女生数量,聚会次数,接下来每个男生一行,内容是男生名字,男生喜欢的人的个数,以及喜欢的人的名字(可能一个都不喜欢,可能喜欢好几个),女生亦是如此,之后每次聚会一行,内容是参加聚会人数,聚会人名。每次聚会,希望能找出一个倒霉蛋,要求这个人喜欢参加这次聚会的除ta自己以外的所有人,并且本次参加聚会的所有人都不喜欢ta,那么请输出这样的人的个数以及ta的名字。

思路:因为倒霉蛋要喜欢聚会里的所有人,并不被其他任何一个人喜欢,如果同一场聚会有第二个倒霉蛋,那么ta肯定是被第一个倒霉蛋喜欢的,这就和倒霉蛋的定义不符,因此,每一场要么有一个倒霉蛋,要么没有。因为题目有16000ms,所以我使用了暴力的双层循环,以每个人为假设的倒霉蛋,对聚会所有人遍历,如果有一个人喜欢ta,或者ta不喜欢某个人,那就对ta是倒霉蛋的假设进行否定。关于储存名字,用map构建了人名到这个人喜欢的人的名字的集合的映射。

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<vector>
#include<set>
using namespace std;

map<string,set<string> >mp;//人名到这个人喜欢的人的名字的集合的映射
char s[30030][111];//存每场聚会的人的名字

int main()
{
	int t,n,m,q,num,p;
	string a,b;
	cin>>t;
	while(t--)
	{
		mp.clear();
		cin>>n>>m>>q;
		for(int i=0;i<n;i++)
		{
			cin>>a>>num;
			for(int j=0;j<num;j++)
			{
				cin>>b;
				mp[a].insert(b);
			}
		}
		for(int i=0;i<m;i++)
		{
			cin>>a>>num;
			for(int j=0;j<num;j++)
			{
				cin>>b;
				mp[a].insert(b);
			}
		}
		set<string>::iterator it;
		for(int i=0;i<q;i++)//暴力到窒息的双层循环
		{
			cin>>p;
			for(int j=0;j<p;j++)
			{
				cin>>s[j];
			}
			string ans;
			int bigflag=0;
			for(int j=0;j<p;j++)
			{
				int flag=0;
				for(int k=0;k<p;k++)
				{
					if(mp[s[j]].count(s[k])==0&&j!=k)//如果ta不喜欢聚会的某个人,说明ta不是倒霉蛋
					{
						flag=1;
						break;
					}
					if(mp[s[k]].count(s[j])==1)//如果有个人喜欢ta,说明ta不是倒霉蛋
					{
						flag=1;
						break;
					}
				}
				if(flag==0)//有倒霉蛋找到了,不用找了
				{
					bigflag=1;
					flag=1;
					ans=s[j];
					break;
				}
			}
		if(bigflag==0)//没有倒霉蛋
		{
			cout<<0<<endl;
		}
		else
		{
			cout<<1<<" "<<ans<<endl;
		}
		}
		puts("");//别忘了,不然会PE
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_39396954/article/details/79283699
ZOJ
今日推荐