• 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.
  • 相关阅读:
    重谈MST及Kruskal算法
    小技巧—边权转点权
    JDOJ 1062 过路费
    总结—二分答案求解问题
    CF10D LCIS
    NOIP 2012 摆花
    SDOI 2014 旅行
    CF550C Divisibility by Eight
    CF295C Greg and Friends
    USACO Closing the Farm
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9471254.html
Copyright © 2020-2023  润新知