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距离最远的城市编号,多个距离相同输出编号 ...
随机推荐
- VS打包部署图文具体步骤及程序防卸载的制作(password验证卸载)
1. 在vs2010 选择"新建项目->"其它项目类型"->" Visual StudioInstallerà "安装项目": ...
- Jenkins安装与使用
一.Jenkins简介 Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括: 1.持续的软件版本发布/测试项目. 2.监控外部调用执行的工作 二.下载与安装 下载地址 ...
- Python学习笔记_Python对象
Python学习笔记_Python对象 Python对象 标准类型 其它内建类型 类型对象和type类型对象 Python的Null对象None 标准类型操作符 对象值的比較 对象身份比較 布尔类型 ...
- POJ2208 Pyramids 四面体体积
POJ2208给定四面体六条棱(有序)的长度 求体积 显然用高中立体几何的方法就可以解决. 给出代码 #include<iostream> #include<cstdio> # ...
- 最长回文子串问题 O(n)算法 manacher URAL1297 HDU3068
先来看一道简单的题,ural1297 给定一个1000长度的字符串,求最长回文子串. 看起来很Naive,乱搞一下,O(n^2)都可以解决. 再来看这个题 HDU3068 120个110000长度的字 ...
- 05_锅炉压力案例_java实现
最开始是有机顶盒,后来电视里面都带着一个安卓的设备.现在空调.冰箱.洗衣机都跃跃欲试地想把这个东西加上.海尔出了一款智能冰箱,就是在冰箱门上嵌了一个12寸的屏幕.这个屏幕实际上就是一个安卓的平板似的. ...
- Ubuntu下 VirtualBox的卸载和升级 (转载)
转载:http://blog.csdn.net/li_hai/article/details/8164744 首先,在终端查看已经安装的VirtualBox的版本: $ dpkg -l 查看到版本号, ...
- codevs1297 硬币(背包dp,方案数)
1297 硬币 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 我们知道即使是同一种面值的硬币,它们的重量也有可能不一样, ...
- 微信小程序去除button边框
button::after{ border: none; } 去button的背景
- centos 扩展lrzsz通过xshell 下载安装文件
yum自动安装: yum install lrzsz 手动安装方法如下: 定制安装的linux可能没有把rzsz包安装到系统,这对用securecrt这样的windows工具传输文件特别不方便.为了使 ...