【奇淫技巧】C++理解繼承+結構體封裝 好題 Gym
阿新 • • 發佈:2018-12-31
題目連結
比賽連結
題意:給定n個表示式,m個判斷,每次有A is B,A has B
會有 A is B,B is C = A is C
A has B,b has c ,A has C
A has B ,B is C ,A has C
A is B,B has C, A has C
這樣的合併,請你輸出判斷的結果。
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
struct know :map<string,int >
{
int operator ()(const string &tmp)
{
if(!count(tmp))
{
insert(make_pair(tmp,size()));
}
return at(tmp);
}
}id;
struct node
{
struct Vex
{
vector<int>a;
int s[2][512];
};
struct road
{
int from,to,op;
};
int fa;
vector<Vex>v;
vector<road>e;
node(int n):v(n){}
void add(const road &st)
{
v[st.from].a.push_back(e.size());
//這裡用到了類似前向星的東西
e.push_back(st);
}
void dfs(int u,int is)
{
v[fa].s[is][u] = 1;
int to ;
// int len =v[u].a.size();
// for(int i=0;i<len;i++)
// {
// int k = v[u].a[i];
// to = e[k].to;
// int yy = k;
// k = is&&e[yy].op;
// if(!v[fa].s[k][to])
// {
// dfs(to,fa,k);
// }
// }
for(int y:v[u].a)
{
//
to = e[y].to ;
int jj = is&&e[y].op;
if(!v[fa].s[jj][to])
{
dfs(to,jj);
}
}
}
}exm(512);//注意這裡需要對vector的大小進行初始化
int n,m;
int main()
{
cin>>n>>m;
string t1,t2,t3;
node::road tmp;
for(int i=1; i<=n; i++)
{
cin>>t1>>t2>>t3;
tmp.from = id(t1);
tmp.to =id(t3);
tmp.op = (t2=="is-a");
exm.add(tmp);
}
for(int i=0;i<(int )id.size();i++)
{
exm.fa = i;
exm.dfs(i,1);
}
for(int i=1; i<=m; i++)
{
cin>>t1>>t2>>t3;
int j = (t2=="is-a"?1:0);
int f= exm.v[id(t1)].s[t2=="is-a"][id(t3)];
if(f)printf("Query %d: true\n",i);
else printf("Query %d: false\n",i);
}
return 0;
}