Mahmoud and a Dictionary

Mahmoud and a Dictionary

题目链接:http://codeforces.com/problemset/problem/766/D

并查集

这种涉及到元素的关系的题目自然就想到了并查集。

我们给每个元素设定两个属性值:pre(前驱结点)和rela(与前驱结点的关系),其中,

当rela=0时,表示当前结点x与其前驱结点a[x].pre是同义词;

当rela=1时,表示当前结点x与其前驱结点a[x].pre是反义词。

由于同义词的同义词是同义词,反义词的反义词是同义词,词与词之间的关系符合模2的运算,即

若x和y的关系是1(反义词),y和z的关系是1(反义词),那么x和z的关系就为(1+1)%2=0(同义词)

因此,若x和y有关(x和y在同一个集合),那么就可以根据x,y与它们各自的祖先的关系计算出x与y的关系:

  x与y的关系=(a[x].rela+a[y].rela)%2.

也就可以判断关系是否错误了。

//Orz队友给出了另一种做法:令词i的反义词为i+n; 如果i和j是同义词,那么i+n和j必是反义词。

代码如下:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <map>
 4 #include <string>
 5 #define N 100005
 6 using namespace std;
 7 map<string,int>mp;
 8 struct node{
 9     int pre,rela;
10 }a[N];
11 int n,m,q;
12 void init(){
13     for(int i=0;i<n;++i){
14         a[i].pre=i;
15         a[i].rela=0;
16     }
17 }
18 int Find(int x){
19     if(a[x].pre==x)return x;
20     int p=a[x].pre;
21     a[x].pre=Find(p);
22     a[x].rela=(a[p].rela+a[x].rela)%2;
23     return a[x].pre;
24 }
25 bool Join(int x,int y,int t){
26     int fx=Find(x),fy=Find(y);
27     if(fx==fy){
28         return (a[x].rela+a[y].rela)%2==t;
29     }else{
30         a[fx].pre=fy;
31         a[fx].rela=(t+a[x].rela+a[y].rela)%2;
32         return 1;
33     }
34     return 0;
35 }
36 int query(int x,int y){
37     int fx=Find(x),fy=Find(y);
38     if(fx==fy)return (a[x].rela+a[y].rela)%2+1;
39     else return 3;
40 }
41 int main(void){
42     cout.sync_with_stdio(false);
43     cin>>n>>m>>q;
44     for(int i=0;i<n;++i){
45         string s;
46         cin>>s;
47         mp[s]=i;
48     }
49     init();
50     while(m--){
51         int t;
52         string x,y;
53         cin>>t>>x>>y;
54         if(Join(mp[x],mp[y],t-1))cout<<"YES\n";
55         else cout<<"NO\n";
56     }
57     while(q--){
58         string x,y;
59         cin>>x>>y;
60         cout<<query(mp[x],mp[y])<<"\n";
61     }
62 }
时间: 2024-10-16 08:33:28

Mahmoud and a Dictionary的相关文章

Codeforces Round #396 (Div. 2) D题Mahmoud and a Dictionary(并查集)解题报告

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 discov

【CF766D】Mahmoud and a Dictionary(并查集)

题意:有n个单词,给定m个关系,每个关系要么表示单词a与单词b相同,要么表示单词a与单词b相反. 并且"相同"与"相反"有性质:若a与b相同,b与c相同,则a与c相同(从而单词的相同关系是等价关系): 若a与b相反,b与c相反,则a与c相同.按顺序判断这m个关系是否可以成立,若可以成立,则加上这个关系,否则忽略. 再给定q个询问,每个询问 查询单词a与单词b的关系(相同.相反或未知). n,m,q<=10^5 思路:并查集 设与i相反的单词集合中的代表为fan

codeforces#766 D. Mahmoud and a Dictionary (并查集)

题意:给出n个单词,m条关系,q个询问,每个对应关系有,a和b是同义词,a和b是反义词,如果对应关系无法成立就输出no,并且忽视这个关系,如果可以成立则加入这个约束,并且输出yes.每次询问两个单词的关系,1,同义词,2,反义词,3,不确定 题解:这题思路比较奇特,开辟2*n的并查集的空间,第i+n代表i的反义词所在的树,初始为i+n,也就是说i+n代表i的反义词 #include<bits/stdc++.h> using namespace std; #define ll long long

CF766D Mahmoud and a Dictionary

题面:https://www.luogu.org/problemnew/show/CF766D 本题现将字符串转化为两个元素之间的关系,之后再利用带权并查集的操作进行路径压缩和判断即可,注意这里的种类数为2. Code: #include<bits/stdc++.h> using namespace std; const int N=1e5+5; int fa[N],rnk[N]; map<string,int>ma; void Init(int n) { for(int i=0;

C#中Dictionary的介绍

关键字:C# Dictionary 字典 作者:txw1958原文:http://www.cnblogs.com/txw1958/archive/2012/11/07/csharp-dictionary.html 说明    必须包含名空间System.Collection.Generic     Dictionary里面的每一个元素都是一个键值对(由二个元素组成:键和值)     键必须是唯一的,而值不需要唯一的     键和值都可以是任何类型(比如:string, int, 自定义类型,等等

c# 扩展方法奇思妙用基础篇五:Dictionary&lt;TKey, TValue&gt; 扩展

Dictionary<TKey, TValue>类是常用的一个基础类,但用起来有时确不是很方便.本文逐一讨论,并使用扩展方法解决. 向字典中添加键和值 添加键和值使用 Add 方法,但很多时候,我们是不敢轻易添加的,因为 Dictionary<TKey, TValue>不允许重复,尝试添加重复的键时 Add 方法引发 ArgumentException. 大多时候,我们都会写成以下的样子: var dict = new Dictionary<int, string>()

Linq在Array,List,Dictionary中的应用

Linq在Array,List,Dictionary中的应用 今天在实际工作中需要对array,list,dictionary进行排序,试一试linq,发现非常好用,代码如下: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Text.RegularExpressions; 6 7 namespace Test 8 { 9 cl

.Net——缓存机制(一):利用Dictionary模拟缓存

在计算机的硬件设计中,有一个被反复使用的思想--缓存.同样,在软件设计中,这个思想也可以用来解决数据读取非常耗时带来的性能问题(当然,在时间和空间上,我们要寻找一个平衡点). 首先来看理想的缓存应该是怎么描述的: static Func<T, R> Cache<T, R>(Func<T, R> func) { var mem = new Dictionary<T, R>(); return x => { if (!mem.ContainsKey(x))

JavaScript如何创建dictionary对象

对于JavaScript来说,其自身的Array对象仅仅是个数组,无法提供通过关键字来获取保存的数据,jQuery源码中提供了一种非常好的方式来解决这个问题,先看一下源码: function createCache() { var keys = []; function cache(key, value) { // Use (key + " ") to avoid collision with native prototype // properties (see Issue #157