您的位置:首页 > 其它

Codeforces Round #396 (Div. 2)D. Mahmoud and a Dictionary【带权并查集】

2017-02-09 17:09 459 查看
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, iflike means
love and love is the opposite of
hate, then
like is also the opposite ofhate. 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 thatlove means
like and like is the opposite of
hate, and then he figures out that
hate meanslike, the last relation is absolutely wrong because it makeshate and
like opposite 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 n,m and
q (2 ≤ n ≤ 105,1 ≤ m, q ≤ 105) wheren
is the number of words in the dictionary,m is the number of relations Mahmoud figured out andq is the number of questions Mahmoud asked after telling all relations.

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

Then m lines follow, each of them contains an integert (1 ≤ t ≤ 2) followed by two different wordsxi
andyi which has appeared in the dictionary words. Ift = 1, that means
xi has a synonymy relation withyi, otherwisexi
has an antonymy relation withyi.

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 exceed20 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, output1. 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个关系是已知的,我们要对Q对单词进行关系查询。

其中M个关系,要么两个单词是同义词,要么两个单词是反义词。

对于查询,如果两个单词是同义词,输出1,如果是反义词输出2,如果不能确定输出3.

思路:

如果对带权并查集不是很了解的童鞋们可以先做做这个题,看题解很容易理解:http://blog.csdn.net/mengxiang000000/article/details/51306205?locationNum=1&fps=1

很裸的带权并查集问题。

对于M个关系,同义词我们设定其两个单词之间距离为0.反义词我们设定两个单词距离为1.

那么对于Q个查询,如果两个单词不在同一个集合中,就是3,如果在同一个集合中,查询两个单词到祖先的距离,然后求一个绝对值差得到两个单词之间的距离,如果这个距离%2是0,那么就说明两个单词是同义词,相反就是反义词啦。

Ac代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
int f[1000010];
int sum[1000010];
int find(int x)
{
if(x!=f[x])
{
int pre=f[x];//pre是x的一个父节点。
f[x]=find(f[x]);//递归找祖先。
sum[x]+=sum[pre];
}
return f[x];
}
int main()
{
int n,m,q;
while(~scanf("%d%d%d",&n,&m,&q))
{
for(int i=1;i<=n;i++)f[i]=i,sum[i]=0;
int cont=1;
map<string ,int >s;
for(int i=0;i<n;i++)
{
char name[50];
scanf("%s",name);
if(s[name]==0)s[name]=cont;
cont++;
}
for(int i=0;i<m;i++)
{
int op;
char a[50];
char b[50];
scanf("%d%s%s",&op,a,b);
int x=s[a];int y=s[b];
int xx=find(x);int yy=find(y);
if(xx!=yy)
{
int val=op-1;
f[yy]=xx;
sum[yy]=sum[x]-sum[y]+val;
printf("YES\n");
}
else
{
int dis=abs(sum[y]-sum[x])%2;
if(dis!=op-1)printf("NO\n");
else printf("YES\n");
}
}
while(q--)
{
char a[50];
char b[50];
scanf("%s%s",a,b);
int x=s[a];int y=s[b];
int xx=find(x);
int yy=find(y);
if(xx!=yy)printf("3\n");
else
{
int dis=abs(sum[y]-sum[x])%2;
if(dis==0)printf("1\n");
else printf("2\n");
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Codeforces#396Div. 2
相关文章推荐