Codeforces Gym 101158 F. Three Kingdoms of Bourdelot
2017-07-09 15:06
501 查看
题意
有多个文档。 每个文档都有多行家谱信息。 有两种类型的文档: 正和负, 每行是一对x, y,
如果文档为正: x 是 y 的祖先
如果文档为负: x 不是 y 的祖先
每个文档都可以有正面或负面的理解。 如果文档数量 n 和两个人 p, q 是给定的, 确定是否有一种组合(确定每篇文档的正负),使得满足 p 是 q 的祖先。
解题思路
数据结构。存储
x, y属于哪几篇文档,
存储每篇文档包含的
x, y。
记录二维数组
isAnc[i][j]=1表示 i 是 j 的祖先
对于已确定
x, y, 其对应的文档都应该是正面的,即对应文档中的所有记录均为正确的。根据这些记录的正确性及原本的祖孙关系,产生新的
x, y,判断是否存在
isAnc[i][j] = isAnc[j][i] = 1的情况,存在为
No,否则一定为
Yes。
代码
#include<bits/stdc++.h> using namespace std; const int NAME = 300+10; const int N = 100000 + 10; string p, q, a, b; int n, idx; vector<pair<int, int> > g[1010]; map<string, int> str2int; vector<int> belg[NAME][NAME]; bool isAnc[NAME][NAME], vis[1010]; bool dfs(int ancestor, int son); bool setAncestor(int ancestor, int son) { if(isAnc[son][ancestor] == 1) return false; isAnc[ancestor][son] = 1; for(int i=1;i<=idx;i++) { if(isAnc[i][ancestor] == 1) { if(isAnc[son][i] == 1) return false; else { isAnc[i][son] = 1; if(dfs(i, son) == false) return false; } } if(isAnc[son][i] == 1) { if(isAnc[i][ancestor] == 1) return false; else { isAnc[ancestor][i] = 1; if(dfs(ancestor, i) == false) return false; } } } return true; } bool dfs(int ancestor, int son) { for(int i=0, id;i<belg[ancestor][son].size();i++) { id = belg[ancestor][son][i]; if(vis[id]) continue; vis[id] = 1; for(int j=0;j<g[id].size();j++) { if(setAncestor(g[id][j].first, g[id][j].second) == false) return false; if(dfs(g[id][j].first, g[id][j].second) == false) return false; } } return true; } int main() { cin>>p>>q; str2int[p] = ++idx; str2int[q] = ++idx; scanf("%d", &n); for(int i=1, m;i<=n;i++) { scanf("%d", &m); for(int j=0;j<m;j++) { cin>>a>>b; if(str2int.find(a) == str2int.end()) str2int[a] = ++idx; if(str2int.find(b) == str2int.end()) str2int[b] = ++idx; belg[str2int[a]][str2int[b]].push_back(i); g[i].push_back(make_pair(str2int[a], str2int[b])); } } isAnc[str2int[p]][str2int[q]] = 1; if(dfs(str2int[p], str2int[q])) { for(int i=1;i<=idx;i++) for(int j=i+1;j<=idx;j++) if(isAnc[i][j] == isAnc[j][i] && isAnc[i][j] == 1) { printf("No\n"); return 0; } printf("Yes\n"); } else printf("No\n"); }
相关文章推荐
- Codeforces Gym 101158 B. Quality of Check Digits (模拟)
- [杂题] Codeforces Gym 101190 NEERC 16 L. List of Primes
- Codeforces Gym - 101158 I - Skinny Polygon (扩展欧几里得)
- Codeforces Gym 101158 E. Infallibly Crack Perplexing Cryptarithm (模拟 + 语法分析)
- Codeforces Gym 101158 A. Rearranging a Sequence
- codeforces Gym 100500C D.Hall of Fame 排序
- Codeforces Gym 101158 C. Distribution Center
- CodeForces Gym 100187 A Potion of Immortality
- Codeforces gym 100685 E. Epic Fail of a Genie 贪心
- codeforces gym 2016-2017 NEERC, Moscow Subregional K. Knights of the Old Republic 最小生成树+dp
- Codeforces Gym 100379G Wythoff’s game with three piles 博弈
- codeforces Gym 100187A A. Potion of Immortality
- 【DFS】Gym - 101142C - CodeCoder vs TopForces
- UVA Live 6129 (Codeforces Gym 100642H) Sofa, So Good 最小费用流
- Codeforces Round #277.5 (Div. 2)C——Given Length and Sum of Digits...
- Codeforces Round #277.5 (Div. 2)C——Given Length and Sum of Digits...
- Codeforces Gym 101142 G. Gangsters in Central City (最近公共祖先)
- Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)
- Codeforces Gym 101173 CERC 16 D & BZOJ 4790 Dancing Disks
- Educational Codeforces Round 4 D. The Union of k-Segments 排序