Is-A? Has-A? Who Knowz-A?(图论)

https://nanti.jisuanke.com/t/43372

题意:

类的继承,有两个关系a is-a b表示a是b的子类,a has-a b表示a有个b作为元素,关系可以继承。之后询问关系的正确性

解析:

用bitset维护出所有点的所有父亲和祖先,fa[i]

has-a比较恶心,has-a会链式继承,并且可以继承fa的has-a。所以我暴力拓展边。每次加入has-a的has-a,和fa的has-a,直到集合不变。

代码:

/*
 *  Author : Jk_Chen
 *    Date : 2020-02-29-13.31.24
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
#define debug(x) cerr<<#x<<" = "<<x<<'\n'
const LL mod=1e9+7;
const int maxn=1e4+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/

bitset<500>fa[500],has[500];
unordered_map<string,int>id;int cnt;

bool vis[500];
void dfs_fa(int p){
    if(vis[p])return;
    vis[p]=1;
    rep(i,0,cnt-1){
        if(fa[p][i]){
            dfs_fa(i);
        }
    }
    bitset<500>tmp;
    tmp.reset();
    tmp|=fa[p];
    rep(i,0,cnt-1){
        if(fa[p][i]){
            tmp|=fa[i];
        }
    }
    fa[p]=tmp;
}

bool DF;
void dfs_has(int p){
    if(vis[p])return;
    vis[p]=1;
    rep(i,0,cnt-1){
        if(has[p][i]||fa[p][i]){
            dfs_has(i);
        }
    }
    bitset<500>tmp;
    tmp.reset();
    tmp|=has[p];
    rep(i,0,cnt-1){
        if(has[p][i]||fa[p][i]){
            tmp|=has[i];
        }
    }
    rep(i,0,cnt-1){
        if(tmp[i])
            tmp|=fa[i];
    }
    if(tmp.count()>has[p].count())DF=1;
    has[p]=tmp;
}

int main(){
    int n=rd,m=rd;
    while(n--){
        string a,b;char x[10];
        cin>>a;scanf("%s",x);cin>>b;
        int ida,idb;
        if(id.count(a))ida=id[a];
        else id[a]=ida=cnt++;
        if(id.count(b))idb=id[b];
        else id[b]=idb=cnt++;
        if(x[0]=='i'){
            fa[ida].set(idb);
        }
        else{
            has[ida].set(idb);
        }
    }
    // init
    rep(i,0,cnt-1){
        if(!vis[i])dfs_fa(i);
    }
    rep(i,0,cnt-1)
        fa[i].set(i);
    while(1){
        DF=0;
        mmm(vis,0);
        rep(i,0,cnt-1){
            if(!vis[i])dfs_has(i);
        }
        if(!DF)break;
    }

    int cas=0;
    while(m--){
        cas++;
        string a,b;char x[10];
        cin>>a;scanf("%s",x);cin>>b;
        int ida=id[a],idb=id[b];
        if(x[0]=='i'){
            if(fa[ida][idb])
                printf("Query %d: true\n",cas);
            else
                printf("Query %d: false\n",cas);
        }
        else{
            if(has[ida][idb])
                printf("Query %d: true\n",cas);
            else
                printf("Query %d: false\n",cas);
        }
    }

    return 0;
}
发布了773 篇原创文章 · 获赞 345 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/104594752