题意:
给出一些句子,代表一些名词和动词的关系,然后有一些查询,看查询语句中的关系是否正确。
思路:
按照题意建边,查询时找两个点有没有路径即可。
代码:
#include <cstdio>
#include <sstream>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
map<string,int> mm;
map<string,int> nn;
int tot;
struct E {
int to, next;
}e[400000];
int head[1000];
int to;
void init() {
tot = 1;
to = 1;
mm.clear();
nn.clear();
memset(head, 0, sizeof(head));
}
void add(int u,int v) {
// printf("lalalal %d %d\n",u,v);
e[to].to = v;
e[to].next = head[u];
head[u] = to++;
}
int vis[1000];
int dfs(int u,int v) {
vis[u] = 1;
if(u == v) return true;
for(int i = head[u]; i; i = e[i].next) {
int vv = e[i].to;
if(!vis[vv]) {
if(dfs(vv,v)) {
return 1;
}
}
}
return 0;
}
int main() {
int t;
scanf("%d", &t);
getchar();
int kase = 1;
while (t--) {
init();
string rans="";
printf("Case #%d:\n", kase++);
string sentence;
while(getline(cin, sentence)){
if (sentence == "") {
continue;
}
int senlen = sentence.length();
if (sentence[senlen - 1] == '!') {
break;
}
else if (sentence[senlen - 1] == '.') {
vector<string> word;
stringstream ss(sentence);
string nowstring;
while (ss >> nowstring) {
word.push_back(nowstring);
}
int wordslen = word.size();
word[wordslen - 1] = word[wordslen - 1].substr(0, word[wordslen - 1].length() - 1);
if (word[1] == "are") {
if(mm[word[0]]==0)
mm[word[0]]=tot++;
if(mm[word[2]]==0)
mm[word[2]]=tot++;
add(mm[word[0]],mm[word[2]]);
}
if (word[1] == "can") {
if(mm[word[0]]==0)
mm[word[0]]=tot++;
if(nn[word[2]]==0)
nn[word[2]]=tot++;
add(mm[word[0]],nn[word[2]]);
}
if (word[1] == "which") {
if (word[4] == "can") {
if(nn[word[3]]==0)
nn[word[3]]=tot++;
if(nn[word[5]]==0)
nn[word[5]]=tot++;
// cout<<word[3]<<" "<<word[5]<<endl;
add(nn[word[3]],nn[word[5]]);
}
else if (word[4] == "are") {
if(nn[word[3]]==0)
nn[word[3]]=tot++;
if(mm[word[5]]==0)
mm[word[5]]=tot++;
add(nn[word[3]],mm[word[5]]);
}
}
}
else if (sentence[senlen - 1] == '?') {
memset(vis,0,sizeof(vis));
int ans;
vector<string> word;
stringstream ss(sentence);
string nowstring;
while (ss >> nowstring) {
word.push_back(nowstring);
}
int wordslen = word.size();
word[wordslen - 1] = word[wordslen - 1].substr(0, word[wordslen - 1].length() - 1);
if (word[0] == "are") {
if (word.size() == 3) {
if(mm[word[1]]==0)
mm[word[1]]=tot++;
if(mm[word[2]]==0)
mm[word[2]]=tot++;
int u=mm[word[1]];
int v=mm[word[2]];
ans=dfs(u,v);
// printf("u=%d v=%d\n",u,v);
}
else {
if(nn[word[4]]==0)
nn[word[4]]=tot++;
if(mm[word[5]]==0)
mm[word[5]]=tot++;
int u=nn[word[4]];
int v=mm[word[5]];
ans=dfs(u,v);
// printf("u=%d v=%d\n",u,v);
}
}
if (word[0] == "can") {
if (word.size() == 6) {
if(nn[word[4]]==0)
nn[word[4]]=tot++;
if(nn[word[5]]==0)
nn[word[5]]=tot++;
int u=nn[word[4]];
int v=nn[word[5]];
ans=dfs(u,v);
// printf("u=%d v=%d\n",u,v);
}
else {
if(mm[word[1]]==0)
mm[word[1]]=tot++;
if(nn[word[2]]==0)
nn[word[2]]=tot++;
int u=mm[word[1]];
int v=nn[word[2]];
ans=dfs(u,v);
// printf("u=%d v=%d\n",u,v);
}
}
if(ans)
rans+="Y";
else
rans+="M";
}
}
cout<<rans<<endl;
}
return 0;
}