gym 101673:Is-A? Has-A? Who Knowz-A? (floyd 求传递闭包)

题目描述:高级语言中类有 is-a 和 has-a 的概念(balabala)
题目链接:https://codeforces.com/gym/101673

(训练时最后一小时一顿盲目分析判断要缩点然后求LCA,开始动手写发现has-a的关系不好写。敲了快一个小时之后发现点数不超过500个,已来不及重写)

题解:点数较小的图可以直接用floyd求传递闭包,对于is-a的关系,直接传递is-a的关系即可。
对于has-a的关系,有三种关系可以传递has-a的关系,求has-a关系之前先求出is-a关系的闭包。

(读题有多重要,血的教训)
代码

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int maxn = 1e3 + 10;
map<string,int> mp;
char a[maxn],b[maxn],c[maxn];
int has[maxn][maxn];
int is[maxn][maxn];
int main() {
	scanf("%d%d",&n,&m);
	int tot = 0;
	for(int i = 1; i <= n; i++) {
		scanf("%s%s%s",a,b,c);
		if(!mp[a]) mp[a] = ++tot;
		if(!mp[c]) mp[c] = ++tot;
		if(b[0] == 'i') is[mp[a]][mp[c]] = 1;
		if(b[0] == 'h') has[mp[a]][mp[c]] = 1;
	}
	
	for(int i = 1; i <= tot; i++)
		is[i][i] = 1;
		
	for(int k = 1; k <= tot; k++)
		for(int i = 1; i <= tot; i++)
			for(int j = 1; j <= tot; j++) {
				if(is[i][k] && is[k][j])
					is[i][j] = 1;
			}
		
	for(int k = 1; k <= tot; k++)
		for(int i = 1; i <= tot; i++)
			for(int j = 1; j <= tot; 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;
			}
	
	for(int i = 1; i <= m; i++) {
		scanf("%s%s%s",a,b,c);
		if(!mp[a]) mp[a] = ++tot;
		if(!mp[c]) mp[c] = ++tot;
		if(b[0] == 'i') {
			if(is[mp[a]][mp[c]]) printf("Query %d: true\n",i);
			else printf("Query %d: false\n",i);
		}		
		if(b[0] == 'h') {
			if(has[mp[a]][mp[c]]) printf("Query %d: true\n",i);
			else printf("Query %d: false\n",i);
		}
	} 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值