zoukankan      html  css  js  c++  java
  • lightoj 1407 2-sat

    这题的英语either...or....很蛋疼;

    m中,1:x与y至少一个出席;2:x出席,y随便,x不出席,y也不出席----这有个坑,可以推出y出席x也一定出席(这个关系必须要连上);3x与y至少一个不出席   4,x与y有且只有一个出席。  

    对于k中的数据:我琢磨很久,关系在图上是建不了的,type为1时三个人至少有一个人要出席,则三个都不出席的情况是不允许的,dfs的时候判断一下就是了,同理type为2的情况。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    const int maxn = 1310;
    const int maxe = 100000;
    const int INF = 0x3f3f3f;
    
    int n,m,k;
    struct node{
        int type,x,y,z;
    }a[6];
    
    struct TwoSat{
        int n;
        int mark[maxn*2];
        int s[maxn*2],cnt;
        vector<int> G[maxn*2];
    
        void init(int n){
            this->n = n;
            for(int i=2;i<=2*n+1;i++)  G[i].clear();
            memset(mark,0,sizeof(mark));
        }
        void add_clause1or3(int u,int uval,int v,int vval){
            u = u*2 + uval;      //u与v不共存;
            v = v*2 + vval;
            G[u].push_back(v^1);
            G[v].push_back(u^1);
        }
        void add_clause2(int u,int uval,int v,int vval){
            u = u*2 + uval;
            v = v*2 + vval;
            G[u].push_back(v);
            G[v^1].push_back(u^1);
        }
        void add_clause4(int u,int uval,int v,int vval){
            u = u*2 + uval;
            v = v*2 + vval;
            G[u^1].push_back(v);
            G[u].push_back(v^1);
            G[v^1].push_back(u);
            G[v].push_back(u^1);
        }
    
        bool JudgeWrong(){
            for(int i=0;i<k;i++){
                if(a[i].type == 1){
                    int x = 2*a[i].x+1,y = 2*a[i].y+1,z = 2*a[i].z+1;
                    if(mark[x] && mark[y] && mark[z]) return true;
                }
                if(a[i].type == 2){
                    int x = 2*a[i].x,y = 2*a[i].y,z = 2*a[i].z;
                    if(mark[x] && mark[y] && mark[z]) return true;
                }
            }
            return false;
        }
    
        bool dfs(int u){
            if(mark[u^1])   return false;
            if(mark[u])     return true;
            mark[u] = true;
            s[cnt++] = u;
            if(JudgeWrong())     return false;
    
            for(int i=0;i<G[u].size();i++)
                if(!dfs(G[u][i]))  return false;
            return true;
        }
    
        bool solve(){
            for(int i=2;i<=2*n;i+=2)
                if(!mark[i] && !mark[i+1]){
                    cnt = 0;
                    if(!dfs(i)){
                        while(cnt > 0)    mark[s[--cnt]] = false;       //要回溯;
                        if(!dfs(i+1))  return false;
                    }
                }
    
            return true;
        }
    
        void print(){
            int ans[maxn],pv = 0;
            for(int i=2;i<=2*n;i+=2)
                if(mark[i])  ans[pv++] = i/2;
    
            printf("%d",pv);
            for(int i=0;i<pv;i++)  printf(" %d",ans[i]);
            printf(".
    ");
        }
    
    }solver;
    
    int main()
    {
        //freopen("E:\acm\input.txt","r",stdin);
        int T;
        cin>>T;
        for(int t=1;t<=T;t++){
            scanf("%d %d %d",&n,&m,&k);
            solver.init(n);
            for(int i=1;i<=m;i++){
                int type,x,y;
                scanf("%d %d %d",&type,&x,&y);
                if(type == 1)         solver.add_clause1or3(x,1,y,1);
                else if(type == 2)    solver.add_clause2(x,1,y,1);
                else if(type == 3)    solver.add_clause1or3(x,0,y,0);
                else                  solver.add_clause4(x,0,y,0);
            }
            for(int i=0;i<k;i++)
                scanf("%d %d %d %d",&a[i].type,&a[i].x,&a[i].y,&a[i].z);
            if(solver.solve()){
                printf("Case %d: Possible ",t);
                solver.print();
            }
            else   printf("Case %d: Impossible.
    ",t);
        }
    }
    View Code
  • 相关阅读:
    leetcode 576. Out of Boundary Paths 、688. Knight Probability in Chessboard
    leetcode 129. Sum Root to Leaf Numbers
    leetcode 542. 01 Matrix 、663. Walls and Gates(lintcode) 、773. Sliding Puzzle 、803. Shortest Distance from All Buildings
    leetcode 402. Remove K Digits 、321. Create Maximum Number
    leetcode 139. Word Break 、140. Word Break II
    leetcode 329. Longest Increasing Path in a Matrix
    leetcode 334. Increasing Triplet Subsequence
    leetcode 403. Frog Jump
    android中webView加载H5,JS不能调用问题的解决
    通过nginx中转获取不到IP的问题解决
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3264842.html
Copyright © 2011-2022 走看看