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
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
算法讨论
如果两条线要平行,要么(1)题目直接给出关系 (2)平行与同一条平行的线 (3)垂直与同一条线,首先用哈希给每条街道编码,当x与y平行时,将x和y、x+mo和y+mo分别放入同一集合,垂直时,x和y+mo、x+mo和y,这样当满足第3个要求是x和y将同一集合。
const
mo=245507;
var
f:array[0..mo*2] of longint;
ha:array[0..mo] of string;
function find(x:longint):longint;
begin
if f[x]=x then exit(x);
f[x]:=find(f[x]);
exit(f[x]);
end;
procedure lian(x,y:longint);
var
xx,yy:longint;
begin
xx:=find(x);
yy:=find(y);
if xx<>yy then f[xx]:=yy;
end;
function hh(x:string):longint;
var
i:longint;
begin
hh:=0;i:=1;
while i<=length(x) do
begin
hh:=(hh*53*i+ord(x[i])*i*59) mod mo;
inc(i);
end;
while (ha[hh]<>'')and(ha[hh]<>x) do
hh:=(hh+1) mod mo;
end;
var
n,m,i,x,y:longint;
xx,yy,s:string;
begin
readln(m,n);
for i:=0 to mo*2 do
f[i]:=i;
for i:=1 to m do
begin
readln(s);
xx:=copy(s,1,pos(' ',s)-1);
x:=hh(xx);
if ha[x]='' then ha[x]:=xx;
delete(s,1,pos(' ',s));
yy:=copy(s,1,pos(' ',s)-1);
y:=hh(yy);
if ha[y]='' then ha[y]:=yy;
delete(s,1,pos(' ',s));
if s='parallel' then
begin
lian(x,y);
lian(x+mo,y+mo);
if (find(x)=find(y+mo))or(find(y)=find(x+mo)) then
begin
writeln('Waterloo');
exit;
end;
end
else
begin
lian(x,y+mo);
lian(x+mo,y);
if find(x)=find(y) then
begin
writeln('Waterloo');
exit;
end;
end;
end;
for i:=1 to n do
begin
readln(s);
xx:=copy(s,1,pos(' ',s)-1);
x:=hh(xx);
delete(s,1,pos(' ',s));
y:=hh(s);
if (ha[x]='')or(ha[y]='')or(ha[x]<>xx)or(ha[y]<>s) then
begin
writeln('unknown');
continue;
end
else
if (find(x)=find(y))or(find(x+mo)=find(y+mo)) then
writeln('parallel')
else
if (find(x)=find(y+mo))or(find(x+mo)=find(y)) then
writeln('intersect')
else writeln('unknown');
end;
end.