D. Mahmoud and a Dictionary
time limit per test

4 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Mahmoud wants to write a new dictionary that contains n words and relations between them. There are two types of relations: synonymy (i. e. the two words mean the same) and antonymy (i. e. the two words mean the opposite). From time to time he discovers a new relation between two words.

He know that if two words have a relation between them, then each of them has relations with the words that has relations with the other. For example, if like means love and love is the opposite of hate, then like is also the opposite of hate. One more example: if love is the opposite of hate and hate is the opposite of like, then love means like, and so on.

Sometimes Mahmoud discovers a wrong relation. A wrong relation is a relation that makes two words equal and opposite at the same time. For example if he knows that love means like and like is the opposite of hate, and then he figures out that hate means like, the last relation is absolutely wrong because it makes hate and likeopposite and have the same meaning at the same time.

After Mahmoud figured out many relations, he was worried that some of them were wrong so that they will make other relations also wrong, so he decided to tell every relation he figured out to his coder friend Ehab and for every relation he wanted to know is it correct or wrong, basing on the previously discovered relations. If it is wrong he ignores it, and doesn't check with following relations.

After adding all relations, Mahmoud asked Ehab about relations between some words based on the information he had given to him. Ehab is busy making a Codeforces round so he asked you for help.

Input

The first line of input contains three integers nm and q (2 ≤ n ≤ 105, 1 ≤ m, q ≤ 105) where n is the number of words in the dictionary, m is the number of relations Mahmoud figured out and q is the number of questions Mahmoud asked after telling all relations.

The second line contains n distinct words a1, a2, ..., an consisting of small English letters with length not exceeding 20, which are the words in the dictionary.

Then m lines follow, each of them contains an integer t (1 ≤ t ≤ 2) followed by two different words xi and yi which has appeared in the dictionary words. If t = 1, that means xi has a synonymy relation with yi, otherwise xi has an antonymy relation with yi.

Then q lines follow, each of them contains two different words which has appeared in the dictionary. That are the pairs of words Mahmoud wants to know the relation between basing on the relations he had discovered.

All words in input contain only lowercase English letters and their lengths don't exceed 20 characters. In all relations and in all questions the two words are different.

Output

First, print m lines, one per each relation. If some relation is wrong (makes two words opposite and have the same meaning at the same time) you should print "NO" (without quotes) and ignore it, otherwise print "YES" (without quotes).

After that print q lines, one per each question. If the two words have the same meaning, output 1. If they are opposites, output 2. If there is no relation between them, output 3.

See the samples for better understanding.

Examples
input
3 3 4
hate love like
1 love like
2 love hate
1 hate like
love like
love hate
like hate
hate like
output
YES
YES
NO
1
2
2
2
input
8 6 5
hi welcome hello ihateyou goaway dog cat rat
1 hi welcome
1 ihateyou goaway
2 hello ihateyou
2 hi goaway
2 hi hello
1 hi hello
dog cat
dog hi
hi hello
ihateyou goaway
welcome ihateyou
output
YES
YES
YES
YES
NO
YES
3
3
1
1
2

题意:n个单词。m种两两关系要么word1和word2为同义词,要么为反义词;若word1和word2为同义词,word1和word3为反义词,那么word2和word3也为反义词;若word1和word2为反义词,word1和word3也为反义词,那么word2和word3为同义词;若第i个关系使得两个单词既为同一次也为反义词,那么这个关系为错,并将其抛弃,继续判断后面的关系,最后建立好所有关系。q次查询,判断word1和word2的关系。

思路:最初想的是使用两个并查集来做,近义词一个,反义词一个;随后发现若两个单词为反义词将其合并的做法不对,抛弃。

然后第二个想法是,在father[i]=i的结点上保存该集合的反义词集合,最后发现是正解。

需将普通并查集代码进行一些改变。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
#define N 100005 struct Node
{
int fa,ant;
} father[N]; int Find(int x)
{
if(father[x].fa!=x)
father[x].fa=Find(father[x].fa);
return father[x].fa;
} void Merge(int x,int y) //改进:合并时,将两同义词的反义词合并
{
int fx=Find(x);
int fy=Find(y);
if(fx!=fy)
{
father[fx].fa=fy;
int antfx=father[fx].ant;
int antfy=father[fy].ant;
if(antfx!=antfy&&antfx>&&antfy>)
{
Merge(antfx,antfy);
father[fy].ant=Find(antfx); //更新同义词集合的反义词
father[Find(antfx)].ant=fy; //更新反义词集合反义词
}
else if(antfx>||antfy>)
{
if(antfx>)
{
father[fy].ant=antfx;
father[Find(antfx)].ant=fy;
}
else
{
father[fy].ant=antfy;
father[Find(antfx)].ant=fy;
}
}
}
} map<string,int> index;
int ant[N]; int main()
{
int fa1[N];
int n,m,q; while(scanf("%d%d%d",&n,&m,&q)!=EOF)
{
for(int i=; i<=n; i++)
{
char word[];
scanf("%s",word);
index[word]=i;
father[i].fa=i;
father[i].ant=;
}
for(int i=; i<m; i++)
{
int re;
char word1[],word2[];
scanf("%d%s%s",&re,word1,word2);
if(re==) //指定关系为同义词
{
int f1=Find(index[word1]);
int f2=Find(index[word2]);
if(f1==f2) //已经是同义词
printf("YES\n");
else if(father[f1].ant!=f2) //两词不为反义词,合并
{
Merge(index[word1],index[word2]);
printf("YES\n");
}
else //出现矛盾
printf("NO\n");
}
else if(re==) //指定关系为反义词
{
int f1=Find(index[word1]);
int f2=Find(index[word2]);
if(f1!=f2) //不是近义词
{
if(father[f1].ant>) //word1有反义词,合并word1的反义词和word2
Merge(father[f1].ant,f2);
if(father[f2].ant>) //word2有反义词,合并word2的反义词和word1
Merge(father[f2].ant,f1);
father[Find(f1)].ant=Find(f2); //更新word1所属集合的反义词集合
father[Find(f2)].ant=Find(f1); //更新word2所属集合的反义词集合
printf("YES\n");
}
else
printf("NO\n");
}
}
for(int i=; i<q; i++)
{
char word1[],word2[];
scanf("%s%s",word1,word2);
if(Find(index[word1])==Find(index[word2]))
printf("1\n");
else if(father[Find(index[word1])].ant==Find(index[word2]))
printf("2\n");
else
printf("3\n");
}
}
return ;
}

Codeforces_766_D_(并查集)的更多相关文章

  1. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  2. 关押罪犯 and 食物链(并查集)

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...

  3. 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用

    图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...

  4. bzoj1854--并查集

    这题有一种神奇的并查集做法. 将每种属性作为一个点,每种装备作为一条边,则可以得到如下结论: 1.如果一个有n个点的连通块有n-1条边,则我们可以满足这个连通块的n-1个点. 2.如果一个有n个点的连 ...

  5. [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)

    Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...

  6. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  7. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

  8. Codeforces 731C Socks 并查集

    题目:http://codeforces.com/contest/731/problem/C 思路:并查集处理出哪几堆袜子是同一颜色的,对于每堆袜子求出出现最多颜色的次数,用这堆袜子的数目减去该值即为 ...

  9. “玲珑杯”ACM比赛 Round #7 B -- Capture(并查集+优先队列)

    题意:初始时有个首都1,有n个操作 +V表示有一个新的城市连接到了V号城市 -V表示V号城市断开了连接,同时V的子城市也会断开连接 每次输出在每次操作后到首都1距离最远的城市编号,多个距离相同输出编号 ...

随机推荐

  1. Codeforces Beta Round #2 B. The least round way

    这个2B题还好~~ 题目大意: 给出一个矩阵.从左上走到右下,仅仅能往右或下走.路径中每一个格子有一个数.这些数相乘得出一个数. 求这个数末尾零最少的一条路径. 解题思路: 找出一条路径.乘积得数中素 ...

  2. 2015/12/30 Java语法学习

    ①标识符包括:包名.类名.方法名.变量名.常量名.属性名 标识符书写规则:1,标识符由字母.数字._.$ 组成                      2,数字不能出现在开始位置          ...

  3. UnicodeEncodeError:'latin-1' codec can't encode character

    UnicodeEncodeError:'latin-1' codec can't encode character

  4. Binary safe

    https://en.wikipedia.org/wiki/Binary-safe A binary-safe function is one that treats its input as a r ...

  5. Django的CBV方式讲解

    CBV使用配置 路径url的配置 cbv 顾名知义就是通过类的方法来调用,我们在url中配置为如下路径 url(r'^cbv.html/', views.Cbv.as_view()), 这里的Cbv是 ...

  6. 洛谷P1514 引水入城——dfs

    题目:https://www.luogu.org/problemnew/show/P1514 搜索+DP: 自己想出来的方法第一次80分好高兴! 再改了改就A了,狂喜乱舞: 也就是 dfs,仔细一想第 ...

  7. matlab绘制曲线对比图

    >> clear;>> x1=[0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8];>> y1=[0,0.55,0.69,0.86,0.93,0. ...

  8. FastDFS的实现

    FastDFS的实现 环境 centos7.1节点提供tracker和storage服务 centos7.2,centos7.3只提供storage服务 FastDFS的实现 fastdfs-5.0. ...

  9. js原始数据类型和引用数据类型=>callback数据传输原理

    摘要:js的数据类型有种划分方式为 原始数据类型和 引用数据类型. 原始数据类型 存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置.栈区包括了 变量的标识符和变量的值. ...

  10. bzoj 1707: [Usaco2007 Nov]tanning分配防晒霜【贪心||最大流(?)】

    洛谷上能过的最大流bzoj上T了--但是贪心做法明明在洛谷上比最大流要慢啊--如果是最大流的话就是裸题了吧 说一下贪心,就按照防晒霜排序,然后对每一个防晒霜选一头可以使用的且r最小的牛 就,没了. 贪 ...