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;
}