【CF766D】Mahmoud and a Dictionary(并查集)

题意:有n个单词,给定m个关系,每个关系要么表示单词a与单词b相同,要么表示单词a与单词b相反。

并且“相同”与“相反”有性质:若a与b相同,b与c相同,则a与c相同(从而单词的相同关系是等价关系);

若a与b相反,b与c相反,则a与c相同。按顺序判断这m个关系是否可以成立,若可以成立,则加上这个关系,否则忽略

再给定q个询问,每个询问 查询单词a与单词b的关系(相同、相反或未知)。

n,m,q<=10^5

思路:并查集

设与i相反的单词集合中的代表为fan[i],则x与y相同的条件是:find(fan[x])<>find(y),合并(find(x),find(y)),(find(fan[x]),find(fan[y]))

不同:find(x)<>find(y),合并时类似

询问类似

  1 var a:array[1..110000]of string;
  2     fa,fan:array[1..200000]of longint;
  3     n,m,k,i,x,y,s,que,j,t1,t2,x1,y1,x2,y2:longint;
  4     tmp,mid,t,ch:ansistring;
  5 
  6 procedure swap(var x,y:string);
  7 begin
  8  t:=x; x:=y; y:=t;
  9 end;
 10 
 11 procedure qsort(l,r:longint);
 12 var i,j,t:longint;
 13 begin
 14  i:=l; j:=r; mid:=a[(l+r)>>1];
 15  repeat
 16   while mid>a[i] do inc(i);
 17   while mid<a[j] do dec(j);
 18   if i<=j then
 19   begin
 20    swap(a[i],a[j]);
 21    inc(i); dec(j);
 22   end;
 23  until i>j;
 24  if l<j then qsort(l,j);
 25  if i<r then qsort(i,r);
 26 end;
 27 
 28 function hash(x:string):longint;
 29 var l,r,mid:longint;
 30 begin
 31  l:=1; r:=n;
 32  while l<=r do
 33  begin
 34   mid:=(l+r)>>1;
 35   if a[mid]=x then exit(mid)
 36    else if a[mid]<x then l:=mid+1
 37     else r:=mid-1;
 38  end;
 39 end;
 40 
 41 function find(k:longint):longint;
 42 begin
 43  if k=0 then exit(0);
 44  if fa[k]<>k then fa[k]:=find(fa[k]);
 45  exit(fa[k]);
 46 end;
 47 
 48 procedure union(x,y:longint);
 49 var p,q:longint;
 50 begin
 51  if (x=0)or(y=0) then exit;
 52  p:=find(x); q:=find(y);
 53  if p<>q then fa[p]:=q;
 54 end;
 55 
 56 begin
 57 // assign(input,'cf766d.in'); reset(input);
 58  //assign(output,'cf766d.out'); rewrite(output);
 59  readln(n,m,que);
 60  readln(ch);
 61  k:=length(ch);
 62  s:=0;
 63  for j:=1 to k do
 64  begin
 65   if ch[j]=' ' then begin inc(s); a[s]:=tmp; tmp:=''; continue; end;
 66    tmp:=tmp+ch[j];
 67  end;
 68  inc(s); a[s]:=tmp;
 69 
 70  qsort(1,n);
 71  for i:=1 to n do
 72  begin
 73   fan[i]:=0; fa[i]:=i;
 74  end;
 75  for i:=1 to m do
 76  begin
 77   readln(ch); tmp:=''; s:=0;
 78   k:=length(ch);
 79   for j:=2 to k do
 80   begin
 81    if ch[j]=' ' then
 82    begin
 83     inc(s);
 84     if s=2 then x:=hash(tmp);
 85     tmp:='';
 86     continue;
 87    end;
 88    if (ch[j]>='a')and(ch[j]<='z') then tmp:=tmp+ch[j];
 89   end;
 90   y:=hash(tmp);
 91   x1:=find(x); y1:=find(y);
 92   x2:=find(fan[x1]); y2:=find(fan[y1]);
 93   case ch[1] of
 94    '1':
 95    begin
 96     if x2=y1 then writeln('NO')
 97      else
 98      begin
 99       writeln('YES');
100       union(x1,y1);
101       union(x2,y2);
102       if y2=0 then fan[y1]:=x2;
103      end;
104    end;
105    '2':
106    begin
107     if x1=y1 then writeln('NO')
108      else
109      begin
110       writeln('YES');
111       if x2>0 then union(y1,x2)
112        else fan[x1]:=y1;
113       if y2>0 then union(x1,y2)
114        else fan[y1]:=x1;
115      end;
116    end;
117   end;
118  end;
119  for i:=1 to que do
120  begin
121   readln(ch); tmp:=''; s:=0;
122   k:=length(ch);
123   for j:=1 to k do
124   begin
125    if ch[j]=' ' then
126    begin
127     inc(s);
128     if s=1 then x:=hash(tmp);
129     tmp:='';
130     continue;
131    end;
132    if (ch[j]>='a')and(ch[j]<='z') then tmp:=tmp+ch[j];
133   end;
134   y:=hash(tmp);
135   x1:=find(x); y1:=find(y);
136   x2:=find(fan[x1]); y2:=find(fan[y1]);
137   if x1=y1 then writeln(1)
138    else if (x1=y2)or(x2=y1) then writeln(2)
139     else writeln(3);
140  end;
141  //close(input);
142  //close(output);
143 end.

 

posted on 2017-02-13 20:50  myx12345  阅读(177)  评论(0编辑  收藏  举报

导航