题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3601
题意:
给出人与人之间的关系,是单向的,接下来会有q个party,问party里面的人,存不存在 单恋所有party中的人,而且party中的人没有一个人单恋他,有的话是输出个数和名字,没有就输出0;
思路:
如果存在题目中说的那种人的话,要么只有1个要么没有;所以只要找到这个人就可以直接输出名字和个数1了;用map存编号,set存关系,在找关系的时候用set的count()就行了;(不知道为什么,用STL存数据的时候,一定要编号1开头,下面的代码中 N = 0的话会出错
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<sstream>
#include<vector>
#include<string>
#include<set>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0);
int read(){
int r=0,f=1;char p=getchar();
while(p>'9'||p<'0'){if(p=='-')f=-1;p=getchar();}
while(p>='0'&&p<='9'){r=r*10+p-48;p=getchar();}return r*f;
}
typedef long long ll;
const int Maxn = 30010;
const long long LINF = 1e18;
const int INF = 0x3f3f3f3f;
set<int> G[Maxn];
map<string,int> mp;
string tmp[Maxn];
bool used[Maxn];
int main (void)
{
IOS;
int t,N,M,n,m,q,num;
string u,v;
cin >> t;
while (t--) {
cin >> n >> m >> q;
mp.clear();
for (int i = 0; i <= n+m; ++i) G[i].clear();
N = 1; // 编号1开头
for (int i = 0; i < n+m; ++i) {
cin >> u;
if(!mp[u]) mp[u] = N++;
cin >> num;
for (int j = 0; j < num; ++j) {
cin >> v;
if(!mp[v]) mp[v] = N++;
G[mp[u]].insert(mp[v]);
}
}
bool ok;
for (int i = 0; i < q; ++i) {
cin >> num;
for (int j = 0; j < num; ++j) {
cin >> tmp[j];
used[j] = 0;
}
for (int j = 0; j < num; ++j) {
if(used[j]) continue;
ok = true;
for (int k = 0; k < num; ++k) {
if(j == k) continue;
if(G[mp[tmp[j]]].count(mp[tmp[k]])) used[k] = true; // 一小部分的剪枝,如果k有人喜欢,那k一定不是答案
if(!G[mp[tmp[j]]].count(mp[tmp[k]]) ||
G[mp[tmp[k]]].count(mp[tmp[j]])) { ok = false; break; }
}
if(ok) { cout << "1 " << tmp[j] << endl; break; }
}
if(!ok) cout << "0" << endl;
}
cout << endl;
}
return 0;
}
)