[JSOI2010]满汉全席 2-SAT

https://www.luogu.org/problemnew/show/P4171

意识到图中只有两种不同的菜系:满和汉

并且检查员类似于一个约束,可以发现这就是一个2-sat模型,满和汉分别对应true和false

由于只是检查可行性,只需要判断存在点的true个false存在同一个强连通分量即可。

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<‘0‘ || c>‘9‘){if (c == ‘-‘) f = -1;c = getchar();}
while (c >= ‘0‘&&c <= ‘9‘){x = x * 10 + c - ‘0‘;c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 210;
const int maxm = 2010;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int N,M,K;
struct Edge{
    int to,next;
}edge[maxm << 2];
int head[maxn],tot;
int Low[maxn],dfn[maxn],Stack[maxn],Belong[maxn];
int Index,top,scc;
bool Instack[maxn];
void init(){
    for(int i = 0 ; i <= (N << 1) ; i ++){
        head[i] = -1;
        Low[i] = dfn[i] = Belong[i] = Instack[i] = 0;
    }
    tot = scc = top = Index = 0;
}
void add(int u,int v){
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}
void Tarjan(int u){
    int v;
    Low[u] = dfn[u] = ++Index;
    Stack[top++] = u;
    Instack[u] = true;
    for(int i = head[u]; ~i ; i = edge[i].next){
        v = edge[i].to;
        if(!dfn[v]){
            Tarjan(v);
            if(Low[u] > Low[v]) Low[u] = Low[v];
        }else if(Instack[v] && Low[u] > dfn[v]) Low[u] = dfn[v];
    }
    if(Low[u] == dfn[u]){
        scc++;
        do{
            v = Stack[--top];
            Instack[v] = false;
            Belong[v] = scc;
        }while(v != u);
    }
}
int main(){
//    ios::sync_with_stdio(false);
    int T = read();
    while(T--){
        cin >> N >> M; init();
        for(int i = 1; i <= M ; i ++){
            char op1,op2; int x,y;
            cin >> op1 >> x >> op2 >> y;
            int flag1 = op1 == ‘m‘?1:0;
            int flag2 = op2 == ‘m‘?1:0;
            add(x + N * (flag1 ^ 1),y + N * (flag2 & 1));
            add(y + N * (flag2 ^ 1),x + N * (flag1 & 1));
        }
        for(int i = 1; i <= (N << 1) ; i ++) if(!dfn[i]) Tarjan(i);
        int flag = 1;
        for(int i = 1; i <= N && flag; i ++){
            if(Belong[i] == Belong[i + N]) flag = 0;
        }
        if(flag) puts("GOOD");
        else puts("BAD");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Hugh-Locke/p/10774101.html

时间: 2024-10-07 14:09:56

[JSOI2010]满汉全席 2-SAT的相关文章

BZOJ 1823: [JSOI2010]满汉全席( 2-sat )

2-sat...假如一个评委喜好的2样中..其中一样没做, 那另一样就一定要做, 这样去建图..然后跑tarjan. 时间复杂度O((n+m)*K) ---------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<stack> using na

bzoj1823 JSOI2010 满汉全席 2-SAT 经典建模

这个题其实我一开始看完没有想到2-SAT 而思路巧妙,编程复杂度低也是我选这个题的原因,在3h4t的赛制中非常适合(好像是病句..) 具体的来说就是,因为每种材料都有两个选择,那就是做成满式或者是汉式 那么我们可以考虑,在信息学奥赛中,只有两种选择的有哪些.. 看来只有二分图和2-SAT了? 然后我们注意到,每个选择是互相排斥的,那么这不正好符合2-SAT的性质么?--每个布尔变量只能是成立或者是不成立,这与满式汉式这好一样. 好那如果你已经想到2-SAT了以后这题基本就出来了 因为本题根本不用

【BZOJ1823】[JSOI2010]满汉全席 2-SAT

[BZOJ1823][JSOI2010]满汉全席 Description 满汉全席是中国最丰盛的宴客菜肴,有许多种不同的材料透过满族或是汉族的料理方式,呈现在數量繁多的菜色之中.由于菜色众多而繁杂,只有极少數博学多闻技艺高超的厨师能够做出满汉全席,而能够烹饪出经过专家认证的满汉全席,也是中国厨师最大的荣誉之一. 世界满汉全席协会是由能够料理满汉全席的专家厨师们所组成,而他们之间还细分为许多不同等级的厨师.为了招收新进的厨师进入世界满汉全席协会,将于近日举办满汉全席大赛,协会派遣许多会员当作评审员

Luogu P4171 [JSOI2010]满汉全席(2-SAT)

P4171 [JSOI2010]满汉全席 题意 题目描述 满汉全席是中国最丰盛的宴客菜肴,有许多种不同的材料透过满族或是汉族料理方式,呈现在数量繁多的菜色之中.由于菜色众多而繁杂,只有极少数博学多闻技艺高超的厨师能够做出满汉全席,而能够烹饪出经过专家认证的满汉全席,也是中国厨师最大的荣誉之一.世界满汉全席协会是由能料理满汉全席的专家厨师们所组成,而他们之间还细分为许多不同等级的厨师. 为了招收新进的厨师进入世界满汉全席协会,将于近日举办满汉全席大赛,协会派遣许多会员当作评审员,为的就是要在参赛的

【BZOJ1823】 [JSOI2010]满汉全席

Description 满汉全席是中国最丰盛的宴客菜肴,有许多种不同的材料透过满族或是汉族的料理方式,呈现在數量繁多的菜色之中.由于菜色众多而繁杂,只有极少數博学多闻技艺高超的厨师能够做出满汉全席,而能够烹饪出经过专家认证的满汉全席,也是中国厨师最大的荣誉之一. 世界满汉全席协会是由能够料理满汉全席的专家厨师们所组成,而他们之间还细分为许多不同等级的厨师.为了招收新进的厨师进入世界满汉全席协会,将于近日举办满汉全席大赛,协会派遣许多会员当作评审员,为的就是要在參赛的厨师之中,找到满汉料理界的明日

[BZOJ 1823][JSOI2010]满汉全席(2-SAT)

Description 满汉全席是中国最丰盛的宴客菜肴,有许多种不同的材料透过满族或是汉族的料理方式,呈现在數量繁多的菜色之中.由于菜色众多而繁杂,只有极少數博学多闻技艺高超的厨师能够做出满汉全席,而能够烹饪出经过专家认证的满汉全席,也是中国厨师最大的荣誉之一. 世界满汉全席协会是由能够料理满汉全席的专家厨师们所组成,而他们之间还细分为许多不同等级的厨师.为了招收新进的厨师进入世界满汉全席协会,将于近日举办满汉全席大赛,协会派遣许多会员当作评审员,为的就是要在參赛的厨师之中,找到满汉料理界的明日

【题解】JSOI2010满汉全席

~bzoj1823 第一次接触2-SAT--SAT,即适定性(Satisfiability)的缩写.像名称所说,即满足需求的可能性问题,而k-SAT即每个人有k种需求,已经证明k>2时是一个NP完全问题.所以现在常见的考法便是2-SAT. 这一道题目算是一道裸的2-SAT问题.每一个人有两种需求,那么我们就将每一种食物拆成两个点,一个代表m,一个代表h,可以注意到满足所有人的需求即如果满足不了其中一个,必须满足另一个,所以我们建图的方法为从无法满足要求的点连向必须满足的点,代表若一个点不符合要求

bzoj1823: [JSOI2010]满汉全席

2-SAT. 好像很复杂的样子所以还在慢慢摸索... 这道题只需要tarjan缩点就可以了,如果有一个材料的满式和汉式同时被选中,代表不可能实现. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 5000 + 10; int g[maxn],v[maxn],next[maxn],eid; int n,m,T; int dfn[maxn

2-set 1823: [JSOI2010]满汉全席

这个题告诉我变量循环使用,一定要赋好初值!!!!!! 一定要赋好初值!!!!!!一定要赋好初值!!!!!!一定要赋好初值!!!!!! #include<iostream>#include<cstdio>#include<cstring>using namespace std;int t,n,m,head[205],next[2005],v[2005],cnt,dfn[205],cnt1,low[205];int zhan[205],zhan1[205],top,shu[

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