NCNA 2017 E floyd transitive closure relationship

Floyd consciousness can be used to solve the shortest problem, but the algorithm itself has a process of realizing weight transfer during the implementation process, so floyd can also be used to realize the judgment of the transfer relationship.

This problem is also solved by this method,
so in the future On the issue of relationship transfer, you can first think about it and rely on floyd to see if you can use flyod to realize the relationship can be transferred in this way, but the final result is still different according to different topics, so it is not all the same.

#include <bits/stdc++.h>

using namespace std;
#define inf 0x3f3f3f3f
typedef long long ll;
const int N = 1e3+7;
int n,m,cnt,cas;// cnt代表着不同字符串的个数
map<string,int>mp;// 存放出现过得字符的位置 也就是序号
char gx[N];// 记录两个字符之间传递的关系
char a[N],b[N];// 记录第一个字符是什么 第二是什么
int is[N][N];
int has[N][N];// 分别记录下来两种可能的传递关系

void flyod()
{
    
    
    for(int i = 1;i <= cnt;i ++)
    {
    
    
        is[i][i] = 1;
    }
    for(int k = 1;k <= cnt;k ++)
    {
    
    
        for(int i = 1;i <= cnt;i ++)
        {
    
    
            for(int j = 1;j <= cnt;j ++)
            {
    
    
                if(is[i][k] && is[k][j])
                    is[i][j] = 1;
            }
        }
    }// is 关系的传递
    for(int k = 1;k <= cnt;k ++)
    {
    
    
        for(int i = 1;i <= cnt;i ++)
        {
    
    
            for(int j = 1;j <= cnt;j ++)
            {
    
    
                if(has[i][k]&&has[k][j])
                    has[i][j] = 1;
                if(is[i][k]&&has[k][j])
                    has[i][j] = 1;
                if(has[i][k]&&is[k][j])
                    has[i][j] = 1;
            }
        }
    }// has的传递关系为只要一条边即可传递
}

int main()
{
    
    
    cin>>n>>m;
    for(int i = 1;i <= n;i ++)
    {
    
    
        scanf("%s%s%s",a,gx,b);
        if(mp[a] == 0)
            mp[a] = ++cnt;
        if(mp[b] == 0)
            mp[b] = ++cnt;
        if(gx[0] == 'i')
            is[mp[a]][mp[b]] = 1;
        if(gx[0] == 'h')
            has[mp[a]][mp[b]] = 1;
    }
    flyod();
    for(int i = 1;i <= m;i ++)
    {
    
    
        scanf("%s%s%s",a,gx,b);
        if(mp[a] == 0)
            mp[a] = ++cnt;// 出现没有出现过得点就会被放到后面 这些点也一定 不会被传递到
        if(mp[b] == 0)
            mp[b] = ++cnt;
        if(gx[0] == 'i')
        {
    
    
            printf("Query %d: %s\n",i,is[mp[a]][mp[b]] == 1?"true":"false");
        }
        if(gx[0] == 'h')
        {
    
    
            printf("Query %d: %s\n",i,has[mp[a]][mp[b]] == 1?"true":"false");
        }
    }
}

Guess you like

Origin blog.csdn.net/weixin_45672411/article/details/104594448