Codeforces Gym 101158 F. Three Kingdoms of Bourdelot

题意

有多个文档。 每个文档都有多行家谱信息。 有两种类型的文档: 正和负, 每行是一对 x, y,

  • 如果文档为正: x 是 y 的祖先
  • 如果文档为负: x 不是 y 的祖先

每个文档都可以有正面或负面的理解。 如果文档数量 n 和两个人 p, q 是给定的, 确定是否有一种组合(确定每篇文档的正负),使得满足 p 是 q 的祖先。

解题思路

数据结构。

  • 存储 x, y 属于哪几篇文档,
  • 存储每篇文档包含的 x, y
  • 记录二维数组 isAnc[i][j]=1 表示 i 是 j 的祖先

对于已确定 x, y, 其对应的文档都应该是正面的,即对应文档中的所有记录均为正确的。根据这些记录的正确性及原本的祖孙关系,产生新的 x, y ,判断是否存在 isAnc[i][j] = isAnc[j][i] = 1 的情况,存在为 No ,否则一定为 Yes

代码

#include<bits/stdc++.h>
using namespace std;
const int NAME = 300+10;
const int N = 100000 + 10;
string p, q, a, b;
int n, idx;
vector<pair<int, int> > g[1010];
map<string, int> str2int;
vector<int> belg[NAME][NAME];
bool isAnc[NAME][NAME], vis[1010];
bool dfs(int ancestor, int son);
bool setAncestor(int ancestor, int son)
{
    if(isAnc[son][ancestor] == 1)   return false;
    isAnc[ancestor][son] = 1;
    for(int i=1;i<=idx;i++)
    {
        if(isAnc[i][ancestor] == 1)
        {
            if(isAnc[son][i] == 1)
                return false;
            else {
                isAnc[i][son] = 1;
                if(dfs(i, son) == false)    return false;
            }
        }
        if(isAnc[son][i] == 1)
        {
            if(isAnc[i][ancestor] == 1) return false;
            else {
                isAnc[ancestor][i] = 1;
                if(dfs(ancestor, i) == false)   return false;
            }
        }
    }
    return true;
}
bool dfs(int ancestor, int son)
{
    for(int i=0, id;i<belg[ancestor][son].size();i++)
    {
        id = belg[ancestor][son][i];
        if(vis[id]) continue;
        vis[id] = 1;
        for(int j=0;j<g[id].size();j++)
        {
            if(setAncestor(g[id][j].first, g[id][j].second) == false)
                return false;
            if(dfs(g[id][j].first, g[id][j].second) == false)
                return false;
        }
    }
    return true;
}
int main()
{
    cin>>p>>q;
    str2int[p] = ++idx;
    str2int[q] = ++idx;
    scanf("%d", &n);
    for(int i=1, m;i<=n;i++)
    {
        scanf("%d", &m);
        for(int j=0;j<m;j++)
        {
            cin>>a>>b;
            if(str2int.find(a) == str2int.end())
                str2int[a] = ++idx;
            if(str2int.find(b) == str2int.end())
                str2int[b] = ++idx;
            belg[str2int[a]][str2int[b]].push_back(i);
            g[i].push_back(make_pair(str2int[a], str2int[b]));
        }
    }
    isAnc[str2int[p]][str2int[q]] = 1;
    if(dfs(str2int[p], str2int[q]))
    {
        for(int i=1;i<=idx;i++)
        for(int j=i+1;j<=idx;j++)
            if(isAnc[i][j] == isAnc[j][i] && isAnc[i][j] == 1)
            {
                printf("No\n");
                return 0;
            }
        printf("Yes\n");
    }
    else    printf("No\n");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您提供的链接是Codeforces的一个问题,问题编号为104377。Codeforces是一个知名的在线编程竞赛平台,经常举办各种编程比赛和训练。GymCodeforces的一个扩展包,用于组织私人比赛和训练。您提供的链接指向了一个问题的页面,但具体的问题内容和描述无法通过链接获取。如果您有具体的问题或需要了解关于Codeforces Gym的更多信息,请提供更详细的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [http://codeforces.com/gym/100623/attachments E题](https://blog.csdn.net/weixin_30820077/article/details/99723867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [http://codeforces.com/gym/100623/attachments H题](https://blog.csdn.net/weixin_38166726/article/details/99723856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [CodeforcesPP:Codeforces扩展包](https://download.csdn.net/download/weixin_42101164/18409501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值