题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4096
题目大意:
给若干如下的论断:
noun_phrase are noun_phrase.
noun_phrase can verb_phrase.
everything which can verb_phrase can verb_phrase.
everything which can verb_phrase are noun_phrase.
再给出若干如下询问:
are noun_phrase noun_phrase?
can noun_phrase verb_phrase?
can everything which can verb_phrase verb_phrase?
are everything which can verb_phrase noun_phrase?
问此询问是否是正确的。
算法:
实际上就是一道输入输出题
把每个名词或者动词当作一个点,注意一个词可能既是名词又是动词。
然后如果一个句子中出现的第一个词是A,第二次是B,就连一条A->B的边。
判断时,如果一个句子中出现的第一个词是A,第二次是B,那么如果存在A->B的路径,结论就是正确的。
需要注意的trick是。可能出现"are A A?"和"can everything which can A A?"的情况,这种情况无论A是否出现过,结论都是正确的。
注:我的代码目前在uva可以AC但是在HDOJ还是TLE,等到我有时间会继续优化,抱歉。
代码如下:
#include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<climits> #include<cmath> #include<algorithm> #include<queue> #include<vector> #include<stack> #include<set> #include<map> #define INF 0x3f3f3f3f using namespace std; const int maxn = 2010; const int maxm = 1010; string word[6]; map <string, int> hash[2]; bool vis[maxn << 1]; char s[100000]; int head[maxn << 1], nxt[maxm], to[maxm]; int E = 0; void dfs(int u, int des) { vis[u] = true; if(vis[des]) { return; } for(int i = head[u]; i != -1; i = nxt[i]) { int v = to[i]; if(! vis[v]) { dfs(v, des); } } } void addedge(int x, int y) { to[E] = y; nxt[E] = head[x]; head[x] = E ++; } inline int ffind(string ss, int flg) { map <string, int> :: iterator it; it = hash[flg].find(ss); int x = hash[flg].size(); if(it == hash[flg].end()) { hash[flg][ss] = x; } else { x = it -> second; } return x + flg * maxn; } int main() { int cas; scanf("%d", &cas); gets(s); for(int T = 1; T <= cas; T ++) { printf("Case #%d:\n", T); hash[0].clear(); hash[1].clear(); memset(head, -1, sizeof(head)); E = 0; while(gets(s)) { int cot = 0; if(s[strlen(s) - 1] == '!') { puts(""); break; } string ss = ""; for(int i = 0; s[i]; i ++) { if(s[i] == ' ' || s[i] == '.' || s[i] == '?') { word[cot ++] = ss; ss = ""; } else { ss += s[i]; } } int x, y; if(s[strlen(s) - 1] == '.') { if(cot == 3) { if(word[1][0] == 'a') { x = ffind(word[0], 0); y = ffind(word[2], 0); } else { x = ffind(word[0], 0); y = ffind(word[2], 1); } } else { if(word[4][0] == 'c') { x = ffind(word[3], 1); y = ffind(word[5], 1); } else { x = ffind(word[3], 1); y = ffind(word[5], 0); } } addedge(x, y); } else { if(cot == 3) { if(word[0][0] == 'a') { x = ffind(word[1], 0); y = ffind(word[2], 0); } else { x = ffind(word[1], 0); y = ffind(word[2], 1); } } else { if(word[0][0] == 'c') { x = ffind(word[4], 1); y = ffind(word[5], 1); } else { x = ffind(word[4], 1); y = ffind(word[5], 0); } } memset(vis, 0, sizeof(vis)); dfs(x, y); if(vis[y]) { putchar('Y'); } else { putchar('M'); } } } } return 0; }