Codeforces_766_D_(并查集)
4 seconds
256 megabytes
standard input
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.
The first line of input contains three integers n, m 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.
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.
3 3 4
hate love like
1 love like
2 love hate
1 hate like
love like
love hate
like hate
hate like
YES
YES
NO
1
2
2
2
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
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_(并查集)的更多相关文章
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- 关押罪犯 and 食物链(并查集)
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- bzoj1854--并查集
这题有一种神奇的并查集做法. 将每种属性作为一个点,每种装备作为一条边,则可以得到如下结论: 1.如果一个有n个点的连通块有n-1条边,则我们可以满足这个连通块的n-1个点. 2.如果一个有n个点的连 ...
- [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)
Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1878 Solved: 846[Submit][Status ...
- Codeforces 731C Socks 并查集
题目:http://codeforces.com/contest/731/problem/C 思路:并查集处理出哪几堆袜子是同一颜色的,对于每堆袜子求出出现最多颜色的次数,用这堆袜子的数目减去该值即为 ...
- “玲珑杯”ACM比赛 Round #7 B -- Capture(并查集+优先队列)
题意:初始时有个首都1,有n个操作 +V表示有一个新的城市连接到了V号城市 -V表示V号城市断开了连接,同时V的子城市也会断开连接 每次输出在每次操作后到首都1距离最远的城市编号,多个距离相同输出编号 ...
随机推荐
- poj 2728 最优比例生成树(01分数规划)模板
/* 迭代法 :204Ms */ #include<stdio.h> #include<string.h> #include<math.h> #define N 1 ...
- 2016/2/21 JavaScript简介
1,javaScript 是什么? 是脚本语言,需要有宿主文件,它的宿主文件是HTML文件.2,它与Java什么关系? 没有什么直接的关系,Java是Sun公司(被Oracle收购了), netspa ...
- 单条insert
ugc_l = browser.find_elements_by_class_name('ugc-item') try: myl = [{'statistics': i.text.replace('阅 ...
- aarch64-linux-gnu交叉编译Qt4.7.3
到 Qt 官网下载合适的 Qt 版本,地址:http://download.qt-project.org/archive/qt/ 1.环境搭建: 1.安装automake.libtool 和主机上的 ...
- ThinkAndroid框架
ThinkAndroid简介 ThinkAndroid是一个免费的开源的.简易的.遵循Apache2开源协议发布的Android开发框架,其开发宗旨是简单.快速的进行 Android应用程序的开发,包 ...
- MAC OS brew安装MNMP
安装HomeBrew Brew是Mac下面的包管理工具,就像centos下面的yum一样.HomeBrew可以通过ruby来安装,mac系统是自带ruby的,所以只要在终端运行下面的代码即可安装Hom ...
- 32.ExtJS简单的动画效果
转自:http://blog.sina.com.cn/s/blog_74684ec501015lhq.html 说明:这篇文章的大部分内容来源于网上,经过自己实现其效果后,整理如下: 在进行 Java ...
- Java properties配置文件
Java中的配置文件常为properties文件,格式为文本文件,文件内容的格式是“键=值”格式.注释信息使用“#”来注释. Properties类的常用方法 String getProperty(S ...
- mycat登录报错Host 'XXX' is blocked because of many connection errors的另一种解决思路
报错时机 使用了mycat,而不是单纯使用了mysql. 报错信息 ERROR 1129 (HY000): Host '1.23.22.18' is blocked because of many c ...
- NET 编程题
1.C#编写创建一个线程的代码 using System; using System.IO; using System.Threading ; class MyThread{ public int c ...