Ligthoj 1407 Explosion

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1407

题目大意:

有一个机器产生m个限制,限制有4种: 

1.  x or y 至少有1个人参加

2. x不参加 则 y必须不参加,(隐含 y参加 x必须参加

3. x or y 至少有1个人不参加

4. x & y 同时参加 或者不参加

有 k 个人 进行投票,有2种类别

1. x y z 至少有一个人参加

2. x y z 至少有一个人不参加


有n 个人参加会议,m 个机器限制,k个人投票 (3 ≤ n ≤ 1000, 0 ≤ m ≤ 2000, 0 ≤ k ≤ 5)

解题思路:肯定是 2-sat,k比较小直接枚举3^k。剩下的就是一个模板。

纪念一下我写的第二个2-sat的题目。

//#pragma comment(linker,"/STACK:102400000,102400000")
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#include<time.h>
#include<stdlib.h>
#include<ctype.h>
#include<list>
//#include<ext/rope>
#define PB push_back
#define MP make_pair
#define PF push_front
#define lson k<<1
#define rson k<<1|1
using namespace std;
typedef long long ll;
typedef double db;
typedef long double ldb;

const int N = 1005;

/// from 0 to n-1
struct TwoSat
{
    int n;
    vector<int> link[N << 1];
    bool mk[N << 1];
    int ch[5][4], stk[N], top; /// the size of stk is N or N*2 ???
    int k, a[5];
    void setmk()
    {
        for(int i = 0; i < n << 1; i++) mk[i] = false;
    }
    void init(int n, int k)
    {
        this->n = n;
        this->k = k;
        for(int i = 0; i < n << 1; i++) link[i].clear();
        setmk();
    }
    void add(int op, int x, int y)
    {
        if(op == 1) link[x << 1 | 1].PB(y << 1), link[y << 1 | 1].PB(x << 1);
        else if(op == 2) link[x << 1 | 1].PB(y << 1 | 1), link[y << 1].PB(x << 1);
        else if(op == 3) link[x << 1].PB(y << 1 | 1), link[y << 1].PB(x << 1 | 1);
        else
        {
            link[x << 1 | 1].PB(y << 1), link[y << 1 | 1].PB(x << 1);
            link[x << 1].PB(y << 1 | 1), link[y << 1].PB(x << 1 | 1);
        }
    }
    bool dfs(int x)
    {
        if(mk[x ^ 1]) return false;
        if(mk[x]) return true;
        mk[x] = true;
        stk[++top] = x;
        for(int i = 0; i < link[x].size(); i++)
            if(!dfs(link[x][i])) return false;
        return true;
    }
    bool solve()
    {
        for(int i = 0; i < n << 1; i += 2)
        {
            if(!mk[i] && !mk[i + 1])
            {
                top = 0;
                if(!dfs(i))
                {
                    while(top) mk[stk[top--]] = false;
                    if(!dfs(i + 1)) return false;
                }
            }
        }
        return true;
    }
    void input(int j)
    {
        for(int i = 0; i < 4; i++) scanf("%d", &ch[j][i]);
    }
    bool work(int p)
    {
        if(p == k)
        {
            setmk();
            for(int i = 0; i < k; i++)
            {
                int t = abs(a[i]) << 1;
                t -= 2;
                if(a[i] < 0) ++t;
                top = 0;
                if(!dfs(t)) return false;
            }
            if(solve()) return true;
            return false;
        }
        else
        {
            for(int i = 1; i < 4; i++)
            {
                if(ch[p][0] == 1) a[p] = ch[p][i];
                else a[p] = -ch[p][i];
                if(work(p + 1)) return true;
            }
            return false;
        }
    }
    void output()
    {
        int cnt(0);
        for(int i = 0; i < n << 1; i += 2) if(mk[i]) cnt++;
        printf(" %d", cnt);
        for(int i = 0; i < n << 1; i += 2) if(mk[i]) printf(" %d", (i >> 1) + 1);
    }
} st;

int main()
{
#ifdef PKWV
    //    freopen("in.in", "r", stdin);
#endif // PKWV
    int T, cas(1);
    scanf("%d", &T);
    while(T--)
    {
        int n, m, k;
        scanf("%d%d%d", &n, &m, &k);
        st.init(n, k);
        for(int i = 0; i < m; i++)
        {
            int op, x, y;
            scanf("%d%d%d", &op, &x, &y);
            x--, y--;
            st.add(op, x, y);
        }
        for(int i = 0; i < k; i++) st.input(i);
        printf("Case %d: ", cas++);
        if(st.work(0))
        {
            printf("Possible");
            st.output();
            printf(".\n");
        }
        else printf("Impossible.\n");
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/u014076176/article/details/48935435