• Gym 101873D


    题目链接:http://codeforces.com/gym/101873/problem/D

    题意:

    给出 $n$ 个事实,表述为 "XXX are worse than YYY"。再给出 $m$ 个某人说的话,也是表述为 "XXX are worse than YYY",对于每句话都要判断是否正确:

    如果正确,输出 "Fact";如果错误,输出 "Alternative Fact";如果无法判断,输出 "Pants on Fire"。

    题解:

    本题是求传递闭包。

    关于传递闭包,例如有 $A={0,1,2}$,基于 $A$ 的关系集合 $R={<0,0>,<1,0>,<2,2>,<1,2>,<2,1>}$,

    而 $R$ 的传递闭包 $t(R) = {<0,0>,<1,0>,<2,2>,<2,1>,<1,2>,<1,1>,<2,0>}$。

    学过离散数学都知道,可以用warshall算法求传递闭包:

      首先用邻接矩阵 $A$ 表示关系。

      (1)置新矩阵 $A=M$;
      (2)令 $j=1$; 
      (3)对所有 $i$ 如果 $A[i,j] = 1$,则对 $k = 1,2,cdots,n$,$A[i,k] = A[i,k] or A[j,k]$;
      (4)$j+=1$(i是行,j是列);
      (5)如果 $j le n$,则转到步骤(3),否则算法结束。

    for(int j=1;j<=tot;j++) {
        for(int i=1;i<=tot;i++) {
            if(!edge[i][j]) continue;
            for(int k=1;k<=tot;k++) {
                edge[i][k]|=edge[j][k];
            }
        }
    }

    观察一下上述代码,可改成:

    for(int j=1;j<=tot;j++) {
        for(int i=1;i<=tot;i++) {
            for(int k=1;k<=tot;k++) {
                edge[i][k]|=edge[i][j]&edge[j][k];
            }
        }
    }

    然后你就会发现,warshall算法和floyd算法异曲同工,然后你就会发现floyd算法全名是floyd-warshall算法。(QWQ)

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=400+10;
    int n,m;
    int edge[maxn][maxn];
    int tot;
    map<string,int> mp;
    int main()
    {
        cin>>n>>m;
        tot=0;
        mp.clear();
        memset(edge,0,sizeof(edge));
        for(int i=1,u,v;i<=n;i++)
        {
            string s;
            cin>>s;
            if(mp.count(s)) u=mp[s];
            else u=mp[s]=++tot;
            cin>>s; cin>>s; cin>>s;
            cin>>s;
            if(mp.count(s)) v=mp[s];
            else v=mp[s]=++tot;
            edge[u][v]=1;
        }
        for(int j=1;j<=tot;j++) {
            for(int i=1;i<=tot;i++) {
                for(int k=1;k<=tot;k++) {
                    edge[i][k]|=edge[i][j]&edge[j][k];
                }
            }
        }
        for(int i=1,u,v;i<=m;i++)
        {
            string s;
            cin>>s;
            u=mp[s];
            cin>>s; cin>>s; cin>>s;
            cin>>s;
            v=mp[s];
            if(edge[u][v]) printf("Fact
    ");
            else if(edge[v][u]) printf("Alternative Fact
    ");
            else printf("Pants on Fire
    ");
        }
    }
  • 相关阅读:
    MySQL 子查询
    MySQL 多表查询 内连接 和 外连接
    MySQL 分页
    MySQL 常用函数 流程控制
    Envoy基于文件系统的EDS动态配置
    Envoy学习笔记
    dapr入门学习
    浅谈cache
    List的初始化方式
    屌丝公司:设置服务器的时区、时间及时间同步
  • 原文地址:https://www.cnblogs.com/dilthey/p/9911863.html
Copyright © 2020-2023  润新知