zoukankan      html  css  js  c++  java
  • [CF468B] Two Sets

    [CF468B] Two Sets - 2-sat

    Description

    给定 (n) 个数字,要划分成 (A,B) 两个集合。要求对任意 (x),若 (x)(A) 中则 (a-x) 也在 (A) 中,若 (x)(B) 中则 (b-x) 也在 (B) 中。保证数互不相同。

    Solution

    2-sat,点 (i) 表示第 (a_i)(A) 中,点 (i+n) 表示 (a_i)(B)

    对于每个数 (a_i),如果 (a_j=a-a_i),那么 (i o j)

    对于每个数 (a_i),如果 (a_j=b-a_i),那么 (i+n o j+n)

    记录一下中间一个搞错了的地方,实际上也是经常错的(好像以前干过类似事情但自己忘了)
    2-sat 中,当我们正向考虑选 x 必须选 y 时,实际上也意味着选 y' 必须选 x'
    如果不连这条边会出问题

    #include <bits/stdc++.h>
    using namespace std;
    
    #define reset(a) memset((a), 0, sizeof((a)))
    
    const int N = 4001000;
    struct edge
    {
        int to, next;
    } e[N];
    int flag = 0;
    int head_for[N], tot, head_back[N];
    int n, a, b, x[N], m, cnt, turn[N], belong[N], vis[N];
    void add(int x, int y)
    {
        e[++tot].to = y;
        e[tot].next = head_for[x];
        head_for[x] = tot;
        e[++tot].to = x;
        e[tot].next = head_back[y];
        head_back[y] = tot;
    }
    void dfs1(int u)
    {
        int i;
        vis[u] = 1;
        for (i = head_for[u]; i; i = e[i].next)
            if (!vis[e[i].to])
                dfs1(e[i].to);
        turn[++cnt] = u;
    }
    void dfs2(int u)
    {
        belong[u] = cnt;
        vis[u] = 1;
        for (int i = head_back[u]; i; i = e[i].next)
            if (!vis[e[i].to])
                dfs2(e[i].to);
    }
    void kosaraju()
    {
        for (int i = 1; i <= 2 * n; i++)
            if (!vis[i])
                dfs1(i);
        reset(vis);
        cnt = 0;
        for (int i = 2 * n; i >= 1; i--)
            if (!vis[turn[i]])
                cnt++, dfs2(turn[i]);
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin >> n >> a >> b;
    
        for (int i = 1; i <= n; i++)
        {
            cin >> x[i];
        }
    
        map<int, int> val2id;
        for (int i = 1; i <= n; i++)
        {
            val2id[x[i]] = i;
        }
    
        for (int i = 1; i <= n; i++)
        {
            if (val2id[a - x[i]])
            {
                add(i, val2id[a - x[i]]);
                add(i + n, n + val2id[a - x[i]]);
            }
            else
            {
                add(i, i + n);
            }
            if (val2id[b - x[i]])
            {
                add(i + n, n + val2id[b - x[i]]);
                add(i, val2id[b - x[i]]);
            }
            else
            {
                add(i + n, i);
            }
            flag = 0;
        }
    
        kosaraju();
    
        for (int i = 1; i <= n; i++)
            if (belong[i] == belong[i + n])
            {
                cout << "NO";
                return 0;
            }
        cout << "YES
    ";
        for (int i = 1; i <= n; i++)
        {
            cout << (belong[i] < belong[i + n]) << ' ';
        }
        return 0;
    }
    
  • 相关阅读:
    Network (poj1144)
    C. Hongcow Builds A Nation
    ZYB loves Xor I(hud5269)
    D. Chloe and pleasant prizes
    Game(hdu5218)
    约瑟夫环的递推方法
    Misaki's Kiss again(hdu5175)
    Exploration(hdu5222)
    B. Arpa's weak amphitheater and Mehrdad's valuable Hoses
    C. Arpa's loud Owf and Mehrdad's evil plan
  • 原文地址:https://www.cnblogs.com/mollnn/p/14615917.html
Copyright © 2011-2022 走看看