5777. 【NOIP2008模拟】小x玩游戏

Description

        今天,小x因为太无聊,就在玩游戏。这个游戏有两个队伍,然后他们在游戏里面打来打去。
       但小x遇到了难题。他不知道自己的队友是谁。他只知道总共有两个队伍,每队有n个人和很多组击杀情况。他想问你,现在他能否知道两个队伍分别有谁。你可以帮助小x吗?由于小x是个游戏狂魔,所以他玩了很多局游戏。
 

Input

       第一行有一个t,表示小y共玩了t局游戏。
        接下来有t组数据,每组数据第一行有一个n,m,表示每队有n个人,有m组击杀情况,接下来m行每行两个字符串s1,s2,表示s1杀了s2,其中s1,s2的长度均不超过10(数据保证两个字符串都由小写字母组成)。注意一个人可以被击杀多次、一个人可以被曾经杀死过的人给杀死。
 

Output

​总共有t行,每行一个“YES”或“NO”,YES表示符合题目条件,NO表示不符合。
 

Solution

开双hash来记录字符串,然后连边。

然后判断是否合法。先找到一个点,做如下图的操作:

dfs中若有一个点连另一个点的标记相同,则错了,

假设点3可以到点7,则错了。

最后判断A和B的个数是否等于n即可。

代码

  1 const
  2   mo1=10000009;
  3   mo2=10000007;
  4 type
  5   arr=record
  6     y,next:longint;
  7   end;
  8 var
  9   bo:boolean;
 10   n,m,nm,mn,tt:longint;
 11   e:array [0..200001] of arr;
 12   a,b:array [1..11] of longint;
 13   ls,v:array [0..4001] of longint;
 14   ha1,ha2:array [0..mo1,1..2] of longint;
 15 
 16 function hash1(x:longint):longint;
 17 var
 18   i:longint;
 19 begin
 20   i:=x;
 21   while (ha1[i,1]<>0) and (ha1[i,1]<>x) do
 22     i:=(i+1) mod mo1;
 23   exit(i);
 24 end;
 25 
 26 function hash2(x:longint):longint;
 27 var
 28   i:longint;
 29 begin
 30   i:=x;
 31   while (ha2[i,1]<>0) and (ha2[i,1]<>x) do
 32     i:=(i+1) mod mo2;
 33   exit(i);
 34 end;
 35 
 36 procedure add(x,y:longint);
 37 begin
 38   inc(mn);
 39   e[mn].y:=y; e[mn].next:=ls[x];
 40   ls[x]:=mn;
 41 end;
 42 
 43 procedure init;
 44 var
 45   i,j,l,p,t1,t2,k1,k2,kk1,kk2,x,y:longint;
 46   s:string;
 47 begin
 48   fillchar(ha1,sizeof(ha1),0);
 49   fillchar(ls,sizeof(ls),0);
 50   fillchar(e,sizeof(e),0);
 51   readln(n,m);
 52   nm:=0; mn:=0;
 53   for i:=1 to m do
 54     begin
 55       readln(s);
 56       l:=length(s); p:=pos(' ',s);
 57       t1:=0; t2:=0;
 58       for j:=p-1 downto 1 do
 59         begin
 60           t1:=(t1+(ord(s[j])-96)*a[p-j]) mod mo1;
 61           t2:=(t2+(ord(s[j])-96)*b[p-j]) mod mo2;
 62         end;
 63       k1:=hash1(t1); kk1:=hash2(t2);
 64       if ha1[k1,1]=0 then
 65         begin
 66           inc(nm);
 67           ha1[k1,1]:=t1; ha1[k1,2]:=nm;
 68           ha2[kk1,1]:=t2; ha2[kk1,2]:=nm;
 69         end else
 70         if ha2[kk1,1]=0 then
 71         begin
 72           inc(nm);
 73           ha2[kk1,1]:=t2; ha2[kk1,2]:=nm;
 74         end;
 75 
 76       t1:=0; t2:=0;
 77       for j:=l downto p+1 do
 78         begin
 79           t1:=(t1+(ord(s[j])-96)*a[l-j+1]) mod mo1;
 80           t2:=(t2+(ord(s[j])-96)*b[l-j+1]) mod mo2;
 81         end;
 82       k2:=hash1(t1); kk2:=hash2(t2);
 83       if ha1[k2,1]=0 then
 84         begin
 85           inc(nm);
 86           ha1[k2,1]:=t1; ha1[k2,2]:=nm;
 87           ha2[kk2,1]:=t2; ha2[kk2,2]:=nm;
 88         end else
 89         if ha2[kk2,1]=0 then
 90         begin
 91           inc(nm);
 92           ha2[kk2,1]:=t2; ha2[kk2,2]:=nm;
 93         end;
 94         add(ha2[kk1,2],ha2[kk2,2]);
 95         add(ha2[kk2,2],ha2[kk1,2]);
 96     end;
 97 end;
 98 
 99 procedure dfs(x,w:longint);
100 var
101   i:longint;
102 begin
103   if not bo then exit;
104   i:=ls[x]; v[x]:=w;
105   if w=1 then w:=2
106          else w:=1;
107   while i<>0 do
108     begin
109       if v[e[i].y]=0 then dfs(e[i].y,w) else
110         if v[e[i].y]<>w then
111           begin
112             bo:=false;
113             exit;
114           end;
115       i:=e[i].next;
116     end;
117 end;
118 
119 procedure print;
120 var
121   i,ans:longint;
122 begin
123   ans:=0;
124   for i:=1 to nm do
125     if v[i]=1 then inc(ans);
126   if (ans=n) and (nm-ans=n) and bo then writeln('YES')
127                                   else writeln('NO');
128 end;
129 
130 procedure try1;
131 var
132   i:longint;
133 begin
134   a[1]:=1; b[1]:=1;
135   for i:=2 to 10 do
136     begin
137       a[i]:=(a[i-1]*107) mod mo1;
138       b[i]:=(b[i-1]*97) mod mo2;
139     end;
140 end;
141 
142 begin
143   assign(input,'game.in');
144   assign(output,'game.out');
145   reset(input);
146   rewrite(output);
147   try1;
148   readln(tt);
149   while tt>0 do
150     begin
151       init;
152       fillchar(v,sizeof(v),0);
153       bo:=true;
154       dfs(1,1);
155       print;
156       dec(tt);
157     end;
158   close(input);
159   close(output);
160 end.
原文地址:https://www.cnblogs.com/zyx-crying/p/9471254.html