ZOJ 3601 Unrequited Love

题目链接:ZOJ 3601 Unrequited Love

挺有意思的一道题,仔细分析后发现一个组中最多只能有一个符合要求,因为如果有两个,那么这两个本身就是矛盾的。

先设置组内第一个人为king/queen,看他与其后的人之间的关系是否符合题目要求,如果碰到某个人是不符合要求的,那么把这个人设为king/queen,再与他后边的比较,注意这里不需要往前判断,最后如果存在king/queen,把这个king/queen与他之前所有人比较关系,如果全部符合要求,那么这个人就是king/queen,反之,这个组内不存king/queen。

#include <iostream>
#include <set>
#include <map>
#include <cstring>

using namespace std;

const int MAX_N = 30000 + 100;
set <int>_set[MAX_N];
int cnt;
map <string, int> id;

int getID(string str)
{
    if(!id.count(str))
        id[str] = cnt++;
    return id[str];
}
int n, m, q, T;
string person[MAX_N];

int main()
{
    cin >> T;
    while(T--)
    {
        id.clear();
        for(int i = 0; i < MAX_N; i++)
            _set[i].clear();
        cnt = 0;
        string str;
        int num,ID;
        cin >> n >> m >> q;
        for(int i = 0; i < n + m ;i++)
        {
           cin >> str >> num;
           ID = getID(str);
           for(int j = 0; j < num; j++)
           {
               cin >> str;
               _set[ID].insert(getID(str));
           }
        }
        string res;
        int flag;
        for(int i = 0; i < q; i++)
        {
            cin >> num;
            for(int j = 0; j < num; j++)
            {
                cin >> str;
                person[j] = str;
            }
            res = person[0];
            flag = 0;
            for(int j = 1; j < num; j++)
            {
                if(!_set[getID(person[flag])].count(getID(person[j])) || _set[getID(person[j])].count(getID(person[flag])))
                {
                    res = person[j];
                    flag = j;
                }
            }
            for(int j = 0; j < flag; j++)
            {
                if(!_set[getID(person[flag])].count(getID(person[j])) || _set[getID(person[j])].count(getID(person[flag])))
                {
                    res = "";
                    break;
                }
            }
            if(res != "")
                cout << 1 << " " << res << endl;
            else
                cout << 0 <<  endl;
        }
        cout << endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值