zoukankan      html  css  js  c++  java
  • Codeforces468B Two Sets

    题意:输入n,a,b,输入n个数,问这n个数能不能分成两个集合,A集合要满足x在A内那么a-x也要在A内,B集合要满足x在B内那么b-x也要在B内

    题解:每一个数都有两种选择,可以用2-sat,对于数x,如果a-x存在,那么a, a-x,这两个数同时在A集合或者同时在B集合,如果不存在,那么这个数一定不在A集合

    同理对于数x,如果b-x存在,那么b, b-x,这两个数同时在A集合或者同时在B集合,如果不存在,那么这个数一定不在B集合

    #include <bits/stdc++.h>
    #define maxn 101000
    #define INF 0x3f3f3f3f
    typedef long long ll;
    using namespace std;
    struct TwoSAT {
        int n;
        vector<int> G[maxn*2];
        bool mark[maxn*2];
        int S[maxn*2], c;
        bool dfs(int x) {
            if (mark[x^1]) return false;
            if (mark[x]) return true;
            mark[x] = true;
            S[c++] = x;
            for (int i = 0; i < G[x].size(); i++)
                if (!dfs(G[x][i])) return false;
            return true;
        }
        void init(int n) {
            this->n = n;
            for (int i = 0; i < n*2; i++) G[i].clear();
            memset(mark, 0, sizeof(mark));
        }
        void addclause(int x, int xval, int y, int yval) {
            x = x * 2 + xval;
            y = y * 2 + yval;
            G[x].push_back(y);
        }
        bool solve() {
            for(int i = 0; i < n*2; i += 2)
                if(!mark[i] && !mark[i+1]) {
                    c = 0;
                    if(!dfs(i)) {
                        while(c > 0) mark[S[--c]] = false;
                        if(!dfs(i+1)) return false;
                    }
                }
            return true;
        }
    }two;
    int dir[maxn], c[maxn], n, a, b;
    map<int, int>mp;
    int main(){
        scanf("%d%d%d", &n, &a, &b);
        two.init(n);
        for(int i=0;i<n;i++){
            scanf("%d", &c[i]);
            mp[c[i]] = i;
        }
        for(int i=0;i<n;i++){
            if(mp.count(a-c[i]))
                two.addclause(i, 0, mp[a-c[i]], 0), two.addclause(i, 1, mp[a-c[i]], 1);
            else two.addclause(i, 0, i, 1);
            if(mp.count(b-c[i]))
                two.addclause(i, 1, mp[b-c[i]], 1), two.addclause(i, 0, mp[b-c[i]], 0);
            else two.addclause(i, 1, i, 0);
        }
        if(two.solve()){
            printf("YES
    ");
            for(int i=0;i<2*n;i+=2){
                if(two.mark[i]) printf("0 ");
                else printf("1 ");
            }
        }
        else printf("NO
    ");
        return 0;
    }
  • 相关阅读:
    nginx常用配置
    docker 启动常用容器命令
    win10 安装 docker
    Selenium IDE for Google Chrome
    Python use goto statement
    TCP:一个悲伤的故事
    gtx770测评
    三十而立——年终总结
    bilibili自定义调整视频播放速度
    linux-安装docker
  • 原文地址:https://www.cnblogs.com/Noevon/p/8579240.html
Copyright © 2011-2022 走看看