codeforces 468B 2-sat

今天明白了2-SAT;

表示对一对整数之间的关系是否存在

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
const int Maxn = 1e5+10;
int mark[Maxn  << 1];
int s[Maxn * 2],top,tp;
int head[Maxn*2];
map <int,int> mp;
int x[Maxn * 2];
struct  {
    int v,next;
}E[Maxn << 2];
void init(){
    memset(head,-1,sizeof(head));
    memset(E,-1,sizeof(E));
    tp = 0;
}
int n,m,a,b;
void addedge(int u,int v){
    E[tp].v = v;
    E[tp].next = head[u];
    head[u] = tp++;
}
bool dfs(int x){
    if(mark[x^1])return false;
    if(mark[x])return true;
    mark[x] = true;
    s[top++] = x;
    for(int i=head[x];i!=-1;i=E[i].next){
        int v = E[i].v;
        if(!dfs(v))return false;
    }
    return true;
}
bool solve(){
    for(int i=0;i<n*2;i+=2){
        if(!mark[i] && !mark[i+1]){
            top = 0;
            if(!dfs(i)){
                while(top > 0)mark[s[--top]] = false;
                if(!dfs(i+1)) return false;
            }
        }
    }
    return true;
}
int main(){

    init();
    cin >> n >> a >> b;
    for(int i = 1;i<= n;i++){
        scanf("%d",&x[i]);
        mp[x[i]] = i;
    }
    for(int i=1;i<=n;i++){
        int val = x[i],s = i;
        s--;
        int t = mp[a - val];t--;
        if(!mp[a-val])addedge(2*s,2*s+1);
        else {
            addedge(2*s,2*t);
            addedge(2*t+1,2*s+1);
        }
         t=mp[b-val]; t--;
            if(!mp[b-val])
                addedge(2*s+1,2*s);
            else{
                addedge(2*s+1,2*t+1);
                addedge(2*t,2*s);
            }
    }
    if(!solve()){
        puts("NO");
    }
    else {
        printf("YES\n");
        for(int i=0;i<2*n;i+=2){
            if(i!=0)
                printf(" ");
            if(mark[i])
                printf("0");
            else
                printf("1");
        }
        printf("\n");
    }
}
时间: 2024-10-21 11:35:21

codeforces 468B 2-sat的相关文章

codeforces 468B two set(并查集)

codeforces 468B two set(并查集)n+1 表示 B 组 n+2 表示 A 组 按照 这题的做法 应该是 如果 满足 num[ i ] a-num[ i ] 则他们同一组 但不一定 就一定是 都是 A 组 也可能都是 B 组 然而如果不满足这个条件的话,就直接加入 B组 然后如果满足 num[ i ] b-num[ i ] 则加入同一组 然后不满足就 加入 A 组 1 #include <bits/stdc++.h> 2 using namespace std ; 3 4

Codeforces 468B Two Sets(二分图匹配)

题目链接:Codeforces 468B Two Sets 题目大意:给出n个数,要求将n个数分配到两个集合中,集合0中的元素x,要求A-x也再0中,同理1集合. 解题思路:类似二分图匹配的方法. #include <cstdio> #include <cstring> #include <map> #include <stack> #include <algorithm> using namespace std; const int maxn

CodeForces 468B Two Sets 二分匹配

把n个数放到集合A和集合B 使得: 对于某个数x,若x在A集合则 a-x也必须在A集合(若a-x不存在于n个数中,则x不能放在A集合) 放在B集合同理. 输出任意解:每个数放在哪个集合里(允许n个数都放一个集合) 思路: 类似二分匹配的做法. [java] view plaincopy import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collecti

Codeforces 468B Two Sets 并查集

题目大意:给出n个数,要求将n个数分配到两个集合中,集合0中的元素x,要求A-x也再0中,同理1集合. 写了几个版本,一直WA在第8组数据...最后参考下ans,写了并查集过了 学到:1.注意离散的逻辑思维,官方答案的 从条件推逆否命题 2.并查集做法:fa[find(i)]=mp[a-p[i]] ? find(a-p[i]) : find(n+2); 3.离散化然后hash的方法,用map时间还是承受得住的,写起来也简单 //#pragma comment(linker, "/STACK:10

Codeforces 424A ()

Squats Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Submit Status Description Pasha has many hamsters and he makes them work out. Today, n hamsters (n is even) came to work out. The hamsters lined up and each hamster e

codeforces A. Shaass and Oskols 题解

Shaass has decided to hunt some birds. There are n horizontal electricity wires aligned parallel to each other. Wires are numbered 1 to n from top to bottom. On each wire there are some oskols sitting next to each other. Oskol is the name of a delici

Codeforces掉分记 round318(div2)

Codeforces掉分记 round318(div2) 又升回紫名了233,这一次就差一点点就AK了,还没有AK过. (以下题目描述摘自codeforces) A题 Bear and Elections 题目描述 Limak is a grizzly bear who desires power and adoration. He wants to win in upcoming elections and rule over the Bearland. There are n candida

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多

Codeforces 124A - The number of positions

题目链接:http://codeforces.com/problemset/problem/124/A Petr stands in line of n people, but he doesn't know exactly which position he occupies. He can say that there are no less than a people standing in front of him and no more than b people standing b