伪Acmer的推理(dfs/bfs)
时间限制:1000MS 内存限制:65535K
提交次数:12 通过次数:9
收入:32
题型: 编程题 语言: C++;C
Description
现在正是期末,在复习离散数学的Acmer遇到了问题,你能帮助他吗? Acmer正在复习的是推理,不过他的推理系统可能与别人的不一样。 (所以说他是一个伪Acmer~。做完这题,请自觉把这里伪Acmer自己定义的概念忘了。。否则到时学离散的时候混淆了概念的话自重。。。) 他的推理系统定义如下: 1.用大写英文字母A-Z表示一个命题。 2.用A→B表示若命题A成立则命题B成立。 3.用A↔B表示A→B且B→A。 (这里2,3皆表示一种逻辑关系。) 推理就是由若干个命题或逻辑关系出发,推出新的命题或逻辑关系。 如,已知A→B和B→C,我们可以推出A→C。 又如,已知A→B和A,我们可以推出B。 再如,如果仅有A、B成立,是不可以推出A→B的。 。。。。。。 现在Acmer已经知道了n个命题或逻辑关系是成立的。而且,他从这些前提出发,又推出了m个新的命题或逻辑关系出来。 不过,他的推理过程并不一定正确。所以,你能告诉他这m个结论中哪些是正确的,哪些是错误的吗?
输入格式
单case输入。 第一行是一个整数n(0<=n<=100)。 接下来n行,每行表示1个已知成立的命题或逻辑关系。 每行首先是一个数字x(1<=x<=3), 若是1,后面接一个大写英文字母,表示一个命题。 若是2,后面接两个大写英文字母,表示逻辑关系→。 若是3,后面接两个大写英文字母,表示逻辑关系↔。 接着是一个整数m(0 < m <= 100)。 接下来m行,每行表示1个要求判断正误的命题或逻辑关系。 每行的格式同上。
输出格式
输出m行。对每个要你判断的结论,正确的话输出“yes”,否则输出“no”。
输入样例
Sample#1: 2 2 A B 2 B C 1 2 A C Sample#2: 1 2 A B 1 1 B Sample#3: 2 2 A B 1 A 1 1 B
输出样例
Sample#1: yes Sample#2: no Sample#3: yes
提示
Sample#不是输入输出的一部分。 注意区别命题和逻辑关系成立的不同。
思路:直接dfs暴力搜一遍,被坑了一下(花了1积分)囧 例子:
0
1
3 Z Z
答案应该是 yes
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/*time memy 31ms 3854k by orc 2015 4 16 */ #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <vector> using namespace std; int vis[30], vis2[30]; int n, x; int t; char u, v, k; vector<int> G[30]; void read_graph() { cin >> n; memset(vis,0,sizeof vis ); for(int i = 0; i < n; ++i) { cin >> t; if(t == 1) { cin >> k; vis[k - 'A'] = 1; continue; }//单个点直接标记为成立 else if(t == 2) { cin >> u >> v; G[u-'A'].push_back(v - 'A'); } else { cin >> u >> v; G[u-'A'].push_back(v - 'A'); G[v - 'A'].push_back(u - 'A'); } } } void dfs_pre(int m) { vis[m] = 1; int num = G[m].size(); for(int i = 0; i < num; ++i) if(! vis[ G[m][i] ]) dfs_pre(G[m][i]); } int dfs(int m,int tag) { int i; vis2[m] = 1; if(m == tag) return 1; int num = G[m].size(); for(i = 0; i < num ; ++i) if(! vis2[ G[m][i] ] ) { if(dfs(G[m][i],tag)) return 1; } if(i >= num ) return 0; } void solve() { int i; read_graph(); for(i=0 ;i < 26 ; ++i)//扫一遍,若某结点之前标记了,其邻接点也是成立的 if(vis[i]) dfs_pre(i); cin >> x; while(x --) { cin >> t; if(t == 1) { cin >> k; if(vis[k - 'A']) cout << "yes" <<endl; else cout << "no" <<endl; continue; } if(t == 2){ memset(vis2, 0 ,sizeof vis2 ); cin >> u >> v; if(u == v) { cout << "yes" <<endl; continue; }//特判 int num = G[u - 'A'].size(); for(i = 0; i < num; ++i) if(! vis2[ G[u - 'A'][i] ]) { if(dfs(G[u - 'A'][i],v - 'A')) break; } if(i >= num) cout << "no" <<endl; else cout << "yes" <<endl; } else{ memset(vis2, 0 ,sizeof vis2 ); cin >> u >> v; if(u == v) { cout << "yes" <<endl; continue; }//特判 int leap , leap2; int num, num2; leap = leap2 = 0; num = G[u - 'A'].size(); num2 = G[v - 'A'].size(); for(i = 0; i < num; ++i)//从 u->v 扫一遍u的邻接点 if(! vis2[ G[u - 'A'][i] ]) { if(leap = dfs(G[u - 'A'][i],v - 'A')) break; } memset(vis2 ,0 ,sizeof vis2); for(i = 0; i< num2 ; ++i)//从 v->u 扫一遍v的邻接点 if(! vis2[ G[v - 'A'][i] ]) { if(leap2 = dfs(G[v - 'A'][i],u - 'A')) break; } if(leap && leap2) cout << "yes" <<endl; else cout << "no" <<endl; } } } int main() { ios::sync_with_stdio(0); solve(); return 0; } /*坑爹例子 0 1 3 Z Z ans:yes */