zjuoj 3601 Unrequited Love
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3601
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
Author: WU, Zejun
Contest: The 9th Zhejiang Provincial Collegiate Programming Contest
分析:
给定一些关系,对于每个人(男孩或女孩),列出他所喜欢的人(允许同性恋),对于每次询问(聚会),求这样一种人:他喜欢所有人,但所有人都不喜欢他
分析:简单分析可知,这种人假如存在,最多只有一个。因为假设有2个这样的人,他们彼此就与题意矛盾。故可以枚举这个人,如何快速枚举?
对于一次聚会,先把第一个人假设为这种人,遍历其后的人,与当前这个人判断关系,若发现这个人不可能是这种人,则把当前遍历的更新为这种人。
扫一遍后,再判断这个人是否真的是,只要和他前面所有的人判断一下即可
AC代码:
1 #include<cstdio> 2 #include<string> 3 #include<set> 4 #include<map> 5 using namespace std; 6 const int N=30005; 7 map<string,int> M; 8 map<string,int>::iterator it; 9 set< pair<int,int> > S; 10 string name[N]; 11 int tol,party[N]; 12 char na[22]; 13 int hash(char *s){ 14 it=M.find(s); 15 if(it!=M.end())return it->second; 16 else { 17 name[++tol]=s; 18 return M[s]=tol; 19 } 20 } 21 void Cin(int x){ 22 int i,k,u,v; 23 for(i=0;i<x;i++){ 24 scanf("%s%d",na,&k); 25 u=hash(na); 26 while(k--){ 27 scanf("%s",na); 28 v=hash(na); 29 S.insert(make_pair(u,v)); 30 } 31 } 32 } 33 int main(){ 34 int T,n,m,q,i,k,ans; 35 scanf("%d",&T); 36 while(T--){ 37 scanf("%d%d%d",&n,&m,&q); 38 M.clear(),S.clear(),tol=0; 39 Cin(n),Cin(m); 40 while(q--){ 41 scanf("%d%s",&k,na); 42 ans=party[0]=M[na]; 43 int p=0; 44 for(i=1;i<k;i++){ 45 scanf("%s",na),party[i]=M[na]; 46 if(S.find(make_pair(ans,party[i]))==S.end()||S.find(make_pair(party[i],ans))!=S.end()){ 47 ans=party[i],p=i; 48 } 49 } 50 for(i=0;i<p;i++){ 51 if(S.find(make_pair(ans,party[i]))==S.end()||S.find(make_pair(party[i],ans))!=S.end())break; 52 } 53 if(i!=p)puts("0"); 54 else printf("1 %s\n",name[ans].c_str()); 55 } 56 puts(""); 57 } 58 return 0; 59 }