Description
在城市里很容易迷路,有的街道一会儿平行一会儿又相交。现在市长为了维护城市形象,他表示:“我们的街道要么平行,要么垂直相交,不存在其他关系”。
你作为观察员准备去当地实地考察,得到一些街道之间的关系,这些关系只能是平行和垂直相交两种。
输入这些街道的关系,同时提出一些新的问题,你来帮忙回答。
Input
输入第一行包含两个整数M和N(1<=M,N<=100000),接下来M行每行包含一个考察结果,每个考察结果包含三个用若干个空格隔开的单词组成:两个街道的名字和“parallel”或“intersect”表示这两条街道之间的关系,每个街道的名字由不超过100个大写或小写字母组成。
接下来N行描述N次询问,每行输入两个由若干个空格隔开的街道名。
Output
如果考察结果与市长的话有矛盾,则输出“Waterloo”,否则输出N行,第i行对应第i次询问的结果,有“parallel”、“intersect”和“unknown”三种情况,分别表示“平行”、“垂直相交”以及“不知道”
Sample Input
3 3
fourthstreet fifthstreet parallel
fifthstreet sixthstreet parallel
fourthavenue fifthstreet intersect
sixthstreet fourthstreet
sixthstreet fourthavenue
sixthstreet King
Sample Output
parallel
intersect
unknown
Data Constraint
Hint
Sample Input2:
2 1
King Weber parallel
King Weber intersect
King Weber
Sample Output2:
Waterloo
【数据说明】
20%的数据 1<=M,N<=100;
100%的数据 1<=M,N<=100000
题目大意:
给你 n n n 条关于街道的关系(平行或垂直),求问任意两条街道的关系。
题解:
种类并查集,
x
x
x 表与
x
x
x 平行的集合,
x
+
N
x+N
x+N 表
⊥
x
⊥x
⊥x 的集合,
在读入时一边更新关系,一边判断是否合法,
若关系为
x
x
x 与
y
y
y 平行,则合并平行
x
,
y
x,y
x,y 的集合,合并
⊥
x
,
⊥
y
⊥x,⊥y
⊥x,⊥y 的集合,
若关系为
x
x
x 与
y
y
y 垂直,则合并平行
x
,
⊥
y
x,⊥y
x,⊥y 的集合,合并
⊥
x
,
y
⊥x,y
⊥x,y 的集合,
若
x
x
x 与
⊥
x
⊥x
⊥x 的平行,则不合法,
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<map>
#define N 400005
using namespace std;
int i,m,t,num;
int fa[2*N];
char c;
string a,b,re;
map<string,int> hash;
string reads() {
c=getchar(),re="";
while ((c>='a'&&c<='z')||(c>='A'&&c<='Z')) {
re+=c; c=getchar();
}
return re;
}
int get(int x) {
if (fa[x]==x) return x;
return fa[x]=get(fa[x]);
}
void merge(int x,int y) {
fa[get(x)]=get(y);
}
int main()
{
scanf("%d %d\n",&m,&t);
for (i=1;i<=m;i++) {
a=reads();
if (!hash[a]) hash[a]=++num,fa[num]=num,fa[num+N]=num+N;
b=reads();
if (!hash[b]) hash[b]=++num,fa[num]=num,fa[num+N]=num+N;
if (reads()=="parallel") {
merge(hash[a],hash[b]);
merge(hash[a]+N,hash[b]+N);
} else {
merge(hash[a]+N,hash[b]);
merge(hash[a],hash[b]+N);
}
if (get(hash[a])==get(hash[b])&&get(hash[a])==get(hash[b]+N)) {
printf("Waterloo"); return 0;
}
}
for (i=1;i<=t;i++) {
a=reads(); b=reads();
if (get(hash[a])==get(hash[b])||get(hash[a]+N)==get(hash[b]+N)) printf("parallel\n"); else
if (get(hash[a]+N)==get(hash[b])||get(hash[a])==get(hash[b]+N)) printf("intersect\n"); else
printf("unknown\n");
}
}