码迷,mamicode.com
首页 > Web开发 > 详细

【题解】 P4171 [JSOI2010]满汉全席

时间:2019-04-22 21:09:01      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:return   状态   har   lock   getch   char s   code   clu   另一个   

\(Descripion:\)

给出 \(n\) 种材料,有 \(m\) 个人,每个人会要求对某种材料进行汉式和满式两种加工。

一种材料只能用一次,问是否有可能满足全部人的要求。(满足定义是有一项他提出的菜做了)。

\(Sample\) \(Input:\)

2
3 4
m3 h1
m1 m2
h1 h3
h3 m2
2 4
h1 m2
m2 m1
h1 h2
m1 h2

\(Sample\) \(Output:\)

GOOD
BAD

\(Solution:\)

这种题有两种状态,只能在这两种状态里选,并且有限制,很明显是 \(2-SAT\) 的题。

考虑把满和汉两种烹饪分成两种状态,连边其实就是 或运算 连边

也就是如果这个点不选,那另一个肯定得选,如果另一个不选,那这个就就得选。

#include<bits/stdc++.h>
using namespace std;
int n,m,k,En,num,cnt,top;
const int N=205,M=2005;
int scc[N+N],head[N+N],dfn[N+N],low[N+N];
int s[N+N],ins[N+N];
char s1[10],s2[10];
struct edge {
    int next,to;
}E[M<<1];
inline void Get(int &a,int &b){
    char ch=getchar();
    while(ch!='h' && ch!='m') ch=getchar();
    a=(ch=='h');
    scanf("%d",&b);
}
inline void add(int from,int to){
    E[++En].next=head[from];
    E[En].to=to;
    head[from]=En;
} 
inline void tarjan(int u){
    dfn[u]=low[u]=++num;
    ins[u]=1;
    s[++top]=u;
    for(int i=head[u];i;i=E[i].next){
        int v=E[i].to;
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(ins[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        scc[u]=++cnt;
        ins[u]=0;
        while(s[top]!=u){
            ins[s[top]]=0;
            scc[s[top]]=cnt;
            top--;
        }
        top--;
    }
}
inline bool two_sat(){
    for(int i=1;i<=n;++i)
        if(scc[i]==scc[i+n]) return false;
    return true;
}
int main(){
    scanf("%d",&k);
    while(k--){
        num=cnt=En=0;
        memset(scc,0,sizeof(scc));
        memset(head,0,sizeof(head));
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(E,0,sizeof(E));
        memset(ins,0,sizeof(ins));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;++i){
            int ax=0,ay=0;
            int bx=0,by=0;
            Get(ax,ay);
            Get(bx,by);
            add(ay+(!ax)*n,by+n*bx);
            add(by+(!bx)*n,ay+n*ax);
        }
        for(int i=1;i<=n+n;++i)
            if(!dfn[i]) tarjan(i);
        if(two_sat()) puts("GOOD");
        else puts("BAD");
    }
    return 0;
}

【题解】 P4171 [JSOI2010]满汉全席

标签:return   状态   har   lock   getch   char s   code   clu   另一个   

原文地址:https://www.cnblogs.com/JCNL666/p/10752681.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!