zoukankan      html  css  js  c++  java
  • [JSOI2010] 满汉全席

    洛谷 P4171 传送门

    bzoj1823 传送门

    2-SAT裸题。

    简单讲一下2-SAT:

    首先把题目给出的种种限制转换为一个图。

    以这道题来说,每种菜看作是两个点,一个点代表做成汉式,另一个代表做成满式。

    然后考虑约束条件:

    比如:评委要求A做成汉式,B做成满式。

    那么如果A做成满式,B就一定是满式;同理,如果B做成汉式,那A一定是汉式。

    所以这么连边:A满-->B满、B汉->A汉。

    不同的题连边方法也略有不同。

    然后对这个图求一个强连通分量。

    显然,如果选择了某个点,那么那个点所在的强连通分量里的所有点都要选择。

    对于1<=X<=n:

    如果存在某个X,X汉和X满在一个强连通分量里,就无解。

    否则有解。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 int k;
     7 int n,m;
     8 int hd[205],to[2005],nx[2005],ec;
     9 
    10 int dish(int id,int kd)
    11 {
    12     return id*2-kd;
    13 }
    14 
    15 void edge(int af,int at)
    16 {
    17     to[++ec]=at;
    18     nx[ec]=hd[af];
    19     hd[af]=ec;
    20 }
    21 
    22 int dfn[205],low[205],dc;
    23 int in[205],st[205],tp;
    24 int gr[205],gsz[205],gc;
    25 
    26 void tarjan(int p)
    27 {
    28     dfn[p]=low[p]=++dc;
    29     st[++tp]=p;
    30     in[p]=1;
    31     for(int i=hd[p];i;i=nx[i])
    32     {
    33         if(!dfn[to[i]])tarjan(to[i]),low[p]=min(low[p],low[to[i]]);
    34         else if(in[to[i]])low[p]=min(low[p],dfn[to[i]]);
    35     }
    36     if(low[p]==dfn[p])
    37     {
    38         gc++;
    39         int np=0;
    40         while(np!=p)
    41         {
    42             np=st[tp--];
    43             gr[np]=gc;
    44             gsz[gc]++;
    45             in[np]=0;
    46         }
    47     }
    48 }
    49 
    50 void clean()
    51 {
    52     memset(hd,0,sizeof(hd));
    53     memset(dfn,0,sizeof(dfn));
    54     memset(low,0,sizeof(low));
    55     memset(gsz,0,sizeof(gsz));
    56     dc=ec=gc=0;
    57 }
    58 
    59 int main()
    60 {
    61     scanf("%d",&k);
    62     while(k--)
    63     {
    64         clean();
    65         scanf("%d%d",&n,&m);
    66         for(int i=1;i<=m;i++)
    67         {
    68             int id[2]={0,0},kd[2],p;
    69             char lim[10];
    70             for(int j=0;j<=1;j++)
    71             {
    72                 scanf("%s",lim+1);
    73                 p=1;
    74                 kd[j]=(lim[p++]=='m');
    75                 while(lim[p]>='0'&&lim[p]<='9')
    76                     id[j]=id[j]*10+lim[p++]-'0';
    77             }
    78             edge(dish(id[0],kd[0]^1),dish(id[1],kd[1]));
    79             edge(dish(id[1],kd[1]^1),dish(id[0],kd[0]));
    80         }
    81         for(int i=1;i<=2*n;i++)
    82             if(!dfn[i])tarjan(i);
    83         int fl=1;
    84         for(int i=1;i<=n;i++)
    85         {
    86             if(gr[dish(i,0)]==gr[dish(i,1)])
    87             {
    88                 fl=0;
    89                 break;
    90             }
    91         }
    92         if(fl)printf("GOOD
    ");
    93         else printf("BAD
    ");
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    php date函数
    jquery AJAX教程
    Magento 批量修改订单状态为 Completed
    php 复习笔记 乱
    正则替换 php js
    magento订单状态修改
    换个心态继续走IT路
    神奇的HTML5,效果超炫,用Google chrome浏览
    PHP $_SERVER参数
    第六章 线程基础
  • 原文地址:https://www.cnblogs.com/cervusy/p/9848898.html
Copyright © 2011-2022 走看看