您的位置:首页 > 理论基础 > 数据结构算法

Codeforces Round #396 (Div. 2)-D. Mahmoud and a Dictionary(关系并查集)

2017-02-08 16:48 513 查看
记录一个菜逼的成长。。

题目链接

题目大意:

n个单词,m个关系,q次查询

有两种关系:

1 a b表示a,b两个单词同义

2 a b表示a,b两个单词反义

如果关系跟之前的关系冲突则无视当前关系

每次查询问两个单词属于1还是2,都不属于则输出3

一看就发现跟poj1703和poj1182两道关系并查集很像,,可以说是结合后的题。

这里我把关系1,2变成0,1刚好是%2后的数

PS:为什么我发现cf的D题总是比C题要好做。。orz.

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
#define clr clear()
map<string ,int>ma;
char a[25],b[25];
const int maxn = 100000 + 10;
int pre[maxn],rel[maxn];
void init()
{
for(int i = 1; i < maxn; i++ ){
pre[i] = i;rel[i] = 0;
}
}
int findr(int x)
{
if(pre[x] == x)return pre[x];
int fx = findr(pre[x]);
rel[x] = (rel[pre[x]] + rel[x]) % 2;
return pre[x] = fx;
}
int unio(int type,int x,int y)
{
int fx = findr(x),fy = findr(y);
if(fx == fy){
if((rel[y] - rel[x] + 2) % 2 != type-1)return 1;
else return 0;
}
pre[fy] = fx;
rel[fy] = (rel[x] - rel[y] + type-1 + 2) % 2;
return 0;
}
int main()
{
int n,m,q;
while(~scanf("%d%d%d",&n,&m,&q)){
ma.clr;
init();
int num = 1;
for( int i = 0; i < n; i++ ){
scanf("%s",a);
ma[a] = num++;
}
while(m--){
int ope;
scanf("%d%s%s",&ope,a,b);
int ret = unio(ope,ma[a],ma[b]);
if(ret)puts("NO");
else puts("YES");
}
while(q--){
scanf("%s%s",a,b);
int fa = findr(ma[a]),fb = findr(ma[b]);
if(fa == fb){
if((rel[ma[a]] + rel[ma[b]]) % 2 == 0)puts("1");
else puts("2");
}
else puts("3");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息