zoukankan      html  css  js  c++  java
  • 题解 洛谷 P4171 【[JSOI2010]满汉全席】

    考虑(2-SAT)

    将汉式看作(0)状态,满式看做(1)状态,将每个材料拆成(01)两个状态。

    (a)(b)连有向边表示的意义为选了(a)后必须选(b)

    那么每次连边的方式如下:

    (add(x_{a oplus 1},y_b),add(y_{b oplus 1},x_a))(x_a)(y_b)为评审员的要求,(x)(y)表示材料,(a)(b)表示状态)

    意义为若没有满足评审员的其中一个要求,则另一个要求必须满足。

    连边后缩点,若发现(x_a)(x_{a oplus 1})在同一强连通分量中,则无解。

    其他的一些实现的处理,就看代码吧。

    (code:)

    #include<bits/stdc++.h>
    #define maxn 4000010
    using namespace std;
    template<typename T> inline void read(T &x)
    {
    	x=0;char c=getchar();bool flag=false;
    	while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
    	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	if(flag)x=-x;
    }
    int t,n,m;
    char str[5];
    struct edge
    {
        int to,nxt;
    }e[maxn];
    int head[maxn],edge_cnt;
    void add(int from,int to)
    {
        e[++edge_cnt]=(edge){to,head[from]};
        head[from]=edge_cnt;
    }
    int dfn_cnt,co_cnt,top;
    int dfn[maxn],low[maxn],co[maxn],st[maxn];
    bool vis[maxn];
    void tarjan(int x)
    {
        dfn[x]=low[x]=++dfn_cnt;
        st[++top]=x;
        vis[x]=true;
        for(int i=head[x];i;i=e[i].nxt)
        {
            int y=e[i].to;
            if(!dfn[y])
            {
                tarjan(y);;
                low[x]=min(low[x],low[y]);
            }
            else if(vis[y])
                low[x]=min(low[x],dfn[y]);
        }
        if(low[x]==dfn[x])
        {
            co_cnt++;
            int now;
            do
            {
                now=st[top--];
                vis[now]=false;
                co[now]=co_cnt;
            }while(now!=x);
        }
    }
    bool check()
    {
        for(int i=1;i<=2*n;++i)
            if(!dfn[i])
                tarjan(i);
        for(int i=1;i<=n;++i)
            if(co[i]==co[i+n])
                return false;
        return true;
    }
    void clear()
    {
        top=dfn_cnt=co_cnt=edge_cnt=0;
        memset(co,0,sizeof(co));
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(vis,0,sizeof(vis));
        memset(head,0,sizeof(head));
    }
    int main()
    {
    	read(t);
        while(t--)
        {
            clear();
            read(n),read(m);
            while(m--)
            {
                int x,y,a,b,len;
                scanf("%s",str);
                if(str[0]=='h') a=0;
                else a=1;
                x=0,len=strlen(str);
                for(int i=1;i<len;++i) x=x*10+str[i]-'0';
                scanf("%s",str);
                if(str[0]=='h') b=0;
                else b=1;
                y=0,len=strlen(str);
                for(int i=1;i<len;++i) y=y*10+str[i]-'0';
                add(x+(a^1)*n,y+b*n),add(y+(b^1)*n,x+a*n);
            }
            if(check()) puts("GOOD");
            else puts("BAD");
        }
    	return 0;
    }
    
  • 相关阅读:
    python json 和 pickle的补充 hashlib configparser logging
    go 流程语句 if goto for swich
    go array slice map make new操作
    go 基础
    块级元素 行内元素 空元素
    咽炎就医用药(慢性肥厚性咽炎)
    春季感冒是风寒还是风热(转的文章)
    秋季感冒 咳嗽 怎么选药
    解决IE浏览器“无法显示此网页”的问题
    常用的 css 样式 记录
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229832.html
Copyright © 2011-2022 走看看