街道
题目链接:jzoj 1499
题目大意
给你一些直线,然后告诉你几对直线的关系。
保证所有直线任意选两个的关系要么是平行要么是垂直。
然后给你若干个询问,每次问你两个之间之间是什么关系。
如果确定,则输出时平行还是垂直,否则输出不确定。
如果给出的关系有矛盾,则直接判断出来,不需回答询问。
思路
考虑用扩展域并查集。
我们把平行的当做同一类,垂直的当做不是同一类。
那只可能有两类,我们就
i
i
i 和
i
+
n
i+n
i+n 两个点分别表示
i
i
i 所在的类和
i
i
i 不在的类。
那矛盾条件就是两个连通了。
那至于判断,就是看是否有连通的,如果都没有,就是不知道。
否则你就看看是
i
,
j
i,j
i,j 连通, 还是
i
,
j
+
n
i,j+n
i,j+n 这种连通了。
然后就好啦。
代码
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include<map>
#include<cstdio>
#include<iostream>
#define rr register
using namespace std;
int n, m, k, fa[400001], aa, bb, cc, num;
string a, b, c;
map <string, int> ma;
int read() {
int an = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9') {
an = an * 10 + c - 48;
c = getchar();
}
return an;
}
string read1() {
char c = getchar();
string temp = "";
while ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
temp += c;
c = getchar();
}
return temp;
}
int find(int x) {
if (fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
void connect(int x, int y) {
int xx = find(x), yy = find(y);
if (xx < yy) fa[yy] = xx;
else if (xx > yy) fa[xx] = yy;
}
int main() {
n = read();
m = read();
for (rr int i = 1; i <= n << 2; i++)
fa[i] = i;
for (rr int i = 1; i <= n; i++) {
a = read1();
b = read1();
c = read1();
if (!ma[a]) ma[a] = ++num;
if (!ma[b]) ma[b] = ++num;
if (c[0] == 'p') {
connect(ma[a], ma[b]);
connect(ma[a] + n + n, ma[b] + n + n);
if (find(ma[a]) == find(ma[b] + n + n) || find(ma[a] + n + n) == find(ma[b])) {
puts("Waterloo");
return 0;
}
}
else {
connect(ma[a], ma[b] + n + n);
connect(ma[a] + n + n, ma[b]);
if (find(ma[a]) == find(ma[b]) || find(ma[a] + n + n) == find(ma[b] + n + n)) {
puts("Waterloo");
return 0;
}
}
}
for (rr int i = 1; i <= m; i++) {
a = read1();
b = read1();
if (!ma[a] || !ma[b]) puts("unknown");
else if (find(ma[a]) == find(ma[b]) || find(ma[a] + n + n) == find(ma[b] + n + n)) puts("parallel");
else if (find(ma[a]) == find(ma[b] + n + n) || find(ma[a] + n + n) == find(ma[b])) puts("intersect");
else puts("unknown");
}
return 0;
}