bzoj 1823: [JSOI2010]满汉全席

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 using namespace std;
  5 int t,n,m,head[205],next[2005],v[2005],cnt,dfn[205],cnt1,low[205];
  6 int zhan[205],zhan1[205],top,shu[205],shu1;
  7 int du()
  8 {
  9     int a1;
 10     char ch;
 11     ch=getchar();
 12     for(;ch!='m'&&ch!='h';ch=getchar());
 13     scanf("%d",&a1);
 14     if(ch=='m')
 15       return a1*2;
 16     else
 17       return a1*2-1;
 18 }
 19 void jia(int a1,int a2)
 20 {
 21     cnt++;
 22     next[cnt]=head[a1];
 23     head[a1]=cnt;
 24     v[cnt]=a2;
 25     return;
 26 }
 27 void dfs(int a1)
 28 {
 29     cnt1++;
 30     low[a1]=dfn[a1]=cnt1;
 31     zhan[a1]=1;
 32     top++;
 33     zhan1[top]=a1;
 34     for(int i=head[a1];i;i=next[i])
 35       if(!dfn[v[i]])
 36         {
 37             dfs(v[i]);
 38             low[a1]=min(low[a1],low[v[i]]);
 39         }
 40       else
 41         if(zhan[v[i]])
 42           low[a1]=min(low[a1],dfn[v[i]]);
 43     if(low[a1]==dfn[a1])
 44       {
 45         shu1++;
 46         for(int i=zhan1[top];i!=a1;top--,i=zhan1[top])
 47           {
 48             shu[i]=shu1;
 49             zhan[i]=0;
 50             }
 51         top--;
 52         shu[a1]=shu1;
 53         zhan[a1]=0;
 54       }
 55     return;
 56 }
 57 int main()
 58 {
 59     scanf("%d",&t);
 60     for(int i=0;i<t;i++)
 61       {
 62         memset(next,0,sizeof(next));
 63         shu1=0;
 64         top=0;
 65         cnt=0;
 66         cnt1=0;
 67         scanf("%d %d",&n,&m);
 68         for(int i=1;i<=2*n;i++)
 69           head[i]=dfn[i]=0;
 70         for(int j=0;j<m;j++)
 71           {
 72             int a1,a2,b1,b2;
 73             a1=du();
 74             b1=du();
 75             if(a1%2==0)
 76               a2=a1-1;
 77             else
 78               a2=a1+1;
 79             if(b1%2==0)
 80               b2=b1-1;
 81             else
 82               b2=b1+1;
 83             jia(a2,b1);
 84             jia(b2,a1);
 85             }
 86        
 87     for(int i=1;i<=2*n;i++)
 88       if(dfn[i]==0)
 89         dfs(i);
 90     int kg=1;
 91     for(int i=1;i<=n;i++)
 92       if(shu[i*2]==shu[i*2-1])
 93         {
 94             kg=0;
 95             printf("BAD
");
 96             break;
 97         }
 98     if(kg)
 99       printf("GOOD
");
100     }
101   return 0;
102 }

2-set问题,根据评委需求建边,比如h1,h2那m2向h1建边,m1向h2建边。求2-set时用tarjin找环。