zoukankan      html  css  js  c++  java
  • 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
    ";
    55         else cout<<"NO
    ";
    56     }
    57     while(q--){
    58         string x,y;
    59         cin>>x>>y;
    60         cout<<query(mp[x],mp[y])<<"
    ";
    61     }
    62 }
  • 相关阅读:
    vue2.0是不支持通过下标来更改数组的,无法做到响应式
    C# 深拷贝 Bitmap对象示例
    vscode终端中文乱码
    TkbmMemTable使用总结
    openssl 证书概念介绍
    openssl源码介绍
    python变量赋值特性
    openssl安装
    github开源协议选择
    NLP 多分类神经网络
  • 原文地址:https://www.cnblogs.com/barrier/p/6380359.html
Copyright © 2011-2022 走看看