zoukankan      html  css  js  c++  java
  • hihoCoder 1467 2-SAT·hihoCoder音乐节(2-SAT模版)

    #1467 : 2-SAT·hihoCoder音乐节

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    hihoCoder音乐节由hihoCoder赞助商大力主办,邀请了众多嘉宾和知名乐队参与演出。

    音乐会分为上午、下午两场进行,主办方指定了n首歌让乐队进行演唱。每首歌只会被演唱一次,要么在上午要么在下午。

    参加音乐会的嘉宾们对于歌曲的演唱时间有一些要求。具体来说,每位嘉宾会指定两首歌曲的演唱时间(上午或者下午)。如果最后实际的演出安排中,两首歌都没有达到嘉宾的要求,那么嘉宾就会对音乐节不滿意。如嘉宾A的要求是上午《我的滑板鞋》和下午《忐忑》,而最后的演出中上午没有《我的滑板鞋》只有《忐忑》,下午没有《忐忑》只有《我的滑板鞋》,那么嘉宾A是不满意的。

    音乐节主办方自然希望使所有嘉宾满意,但主办方后来发现有可能不存在一种歌曲的安排方案满足所有嘉宾,所以他们希望你判断一下这种情况是否会发生。

    解题方法提示

    输入

    输入第一行包含一个数字 K,代表K组数据。(K≤50)

    对于每一组数据,第一行包含两个非负整数n和m(n≤100,m≤1000),代表有n首歌和m位嘉宾。

    为了方便我们给予歌编号,编号分别从1 到n。接下的m行,每行都代表对应的嘉宾的喜好由一个英文字母(m或h)跟一个数字代表,如m1 代表这个评审喜欢第1首歌上午进行,而h2代表这个评审员喜欢第2首歌下午进行。

    输出

    对于每一组数据,输出一行,如果能满足所有嘉宾的情况,输出GOOD;否则输出BAD。

    样例输入
    2
    3 4
    m3 h1
    m1 m2
    h1 h3
    h3 m2
    2 4
    h1 m2
    m2 m1
    h1 h2
    m1 h2
    样例输出
    GOOD
    BAD

    题目链接:hihoCoder 1467

    给定N个表演,M个要求,每一个限制有两个条件,至少成立一个条件这个限制就算满足,求是否存在这种安排。

    比较模版的一题,显然每一个节目存在矛盾的两个面:要么早上表演,要么晚上表演,因此把一个节目拆成两个点,$i(=i)$代表早上表演,$lnot i(=n+i)$代表晚上表演,那么对于任意一个形如 $alor b$的限制,添加 $lnot a o b$与$lnot b o a$两条有向边,然后用Tarjan求强连通分量,然后遍历每一个节目拆出来的两个点,若发现存在一个节目的$i$与$lnot i$在同一连通分量中,说明这两个处于同样的状态,但事实上不可能共存,因此可以判断为BAD,否则为GOOD

    代码:

    #include <stdio.h>
    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define LC(x) (x<<1)
    #define RC(x) ((x<<1)+1)
    #define MID(x,y) ((x+y)>>1)
    #define CLR(arr,val) memset(arr,val,sizeof(arr))
    #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    typedef pair<int, int> pii;
    typedef long long LL;
    const double PI = acos(-1.0);
    const int N = 210;
    const int M = 1010;
    struct edge
    {
        int to, nxt;
        edge() {}
        edge(int _to, int _nxt): to(_to), nxt(_nxt) {}
    };
    edge E[M << 1];
    int head[N], tot;
    int dfn[N], low[N], st[N], ts, top, belong[N], scc;
    bitset<N>ins;
    
    void init()
    {
        CLR(head, -1);
        tot = 0;
        CLR(dfn, 0);
        CLR(low, 0);
        ts = top = scc = 0;
        CLR(belong, 0);
        ins.reset();
    }
    inline void add(int s, int t)
    {
        E[tot] = edge(t, head[s]);
        head[s] = tot++;
    }
    void Tarjan(int u)
    {
        dfn[u] = low[u] = ++ts;
        ins[u] = 1;
        st[top++] = u;
        int i, v;
        for (i = head[u]; ~i; i = E[i].nxt)
        {
            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 (low[u] == dfn[u])
        {
            ++scc;
            do
            {
                v = st[--top];
                ins[v] = 0;
                belong[v] = scc;
            } while (u != v);
        }
    }
    int main(void)
    {
        int T, n, m, a, b, i;
        char q, p;
        scanf("%d", &T);
        while (T--)
        {
            init();
            scanf("%d%d", &n, &m);
            for (i = 0; i < m; ++i)
            {
                scanf(" %c%d %c%d", &q, &a, &p, &b);
                if (q == 'm' && p == 'm')
                {
                    add(a + n, b);
                    add(b + n, a);
                }
                else if (q == 'm' && p == 'h')
                {
                    add(a + n, b + n);
                    add(b, a);
                }
                else if (q == 'h' && p == 'm')
                {
                    add(a, b);
                    add(b + n, a + n);
                }
                else
                {
                    add(a, b + n);
                    add(b, a + n);
                }
            }
            int sz = n << 1;
            for (i = 1; i <= sz; ++i)
                if (!dfn[i])
                    Tarjan(i);
            bool flag = true;
            for (i = 1; i <= n && flag; ++i)
                if (belong[i] == belong[i + n])
                    flag = false;
            puts(flag ? "GOOD" : "BAD");
        }
        return 0;
    }
  • 相关阅读:
    websocket+nodejs+redis实现消息订阅和发布系统
    nodejs下载图片到本地,根据百度图片查找相应的图片,通过nodejs保存到本地文件夹
    基于vue 2.X和高德地图的vue-amap组件获取经纬度
    获取Class对象的三种方式
    java中的回调机制的理解(小例子)
    URL和URI的区别
    java web开发中各类地址的写法
    ListView性能
    Android中的Handler, Looper, MessageQueue和Thread对应关系
    java几种常用的算法
  • 原文地址:https://www.cnblogs.com/Blackops/p/6505589.html
Copyright © 2011-2022 走看看