2018-2019 ACM-ICPC, Asia Seoul Regional Contest K TV Show Game 2-sat

题目传送门

题意:

  有n个人,k盏灯,灯有红蓝两种颜色,每个人都猜了三种灯的颜色,问如何安排灯的颜色,使得每个人猜的灯至少有两个是对的。

思路:

  很容易想到2-sat,但是显然枚举每个人猜对的情况是不显示的,因为猜对两个和猜对三个两种情况就很难搞了。所以我们枚举每一个人猜的灯错的是哪一盏,如果某一盏错了,那么另外两盏就必须是对的,这样才符合条件。

  我们用一个light的二维vector,保存:$灯的某种颜色,选这个颜色是属于选错的人$,再用一个二维vector名字叫people保存每个人的三种错误情况。

  然后在twosat的函数里枚举每种灯的颜色,如果说某一种颜色对于所有选错的人来说都满足条件(满足dfs),那对于这个灯的颜色选对的人肯定已经是更优的,所以可以这样枚举。

  在dfs中check合法性的时候,就枚举所有选错的人,这个人的其他颜色都必须选对才可以。

  结合文字看代码吧,光靠文字有点难表述清楚。

#pragma GCC optimize (2)
#pragma G++ optimize (2)
#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
#include<cstdio>
#include<vector>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,b,a) for(int i=b;i>=a;i--)
#define clr(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pii pair<int,int >
using namespace std;
typedef long long ll;
const int maxn=10010;
const int inf=0x3f3f3f3f;
ll rd()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
int vis[maxn],sta[maxn],top;
struct node{
    int p1,p2,p3,c1,c2,c3;
}a[maxn];
vector<int >light[maxn],peo[maxn];
int n,k;
bool dfs(int u){
    if(vis[u^1])return false;
    if(vis[u])return true;
    vis[u]=1;
    sta[++top]=u;
    for(auto &x:light[u]){
        for(auto &v:peo[x]){
            if(v==u)continue;
            if(!dfs(v^1))return false;
        }
    }
    return true;
}
int two_sat(int n){
    for(int i=2;i<=n;i+=2){
        if(vis[i]||vis[i^1])continue;
        top=0;
        if(!dfs(i)){
            while(top){vis[sta[top--]]=0;}
            if(!dfs(i^1))return false;
        }
    }
    return true;
}
int main(){
    cin>>k>>n;
    rep(i,1,n){
        char xx,yy,zz;
        scanf("%d %c %d %c %d %c",&a[i].p1,&xx,&a[i].p2,&yy,&a[i].p3,&zz);
        a[i].c1=a[i].p1*2+(xx==‘B‘);
        a[i].c2=a[i].p2*2+(yy==‘B‘);
        a[i].c3=a[i].p3*2+(zz==‘B‘);

        light[a[i].c1^1].push_back(i);
        peo[i].push_back(a[i].c1^1);

        light[a[i].c2^1].push_back(i);
        peo[i].push_back(a[i].c2^1);

        light[a[i].c3^1].push_back(i);
        peo[i].push_back(a[i].c3^1);
    }
    int f=two_sat(2*k);
    if(f==0){
        puts("-1");
    }else{
        for(int i=1;i<=k;i++){
            if(vis[i*2])putchar(‘R‘);
            else putchar(‘B‘);
        }
        puts("");
    }
}
/*
7 5
3 R 5 R 6 B
1 B 2 B 3 R
4 R 5 B 6 B
5 R 6 B 7 B
1 R 2 R 4 R

5 6
1 B 3 R 4 B
2 B 3 R 4 R
1 B 2 R 3 R
3 R 4 B 5 B
3 B 4 B 5 B
1 R 2 R 4 R
*/

原文地址:https://www.cnblogs.com/mountaink/p/11615502.html

时间: 2024-08-30 17:28:10

2018-2019 ACM-ICPC, Asia Seoul Regional Contest K TV Show Game 2-sat的相关文章

2018-2019, ICPC, Asia Yokohama Regional Contest 2018 (Gym - 102082)

2018-2019, ICPC, Asia Yokohama Regional Contest 2018 A - Digits Are Not Just Characters 签到. B - Arithmetic Progressions 题意:从给定的集合中选出最多的数构成等差数列. 题解:数字排序后,设\(dp[i][j]\)表示等差数列最后一个数字为\(a[i]\),倒数第二个数字为\(a[j]\)的最大个数.然后对于每一位枚举 \(i\),\(lower\_bound()\)找有无合法的

ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Krak&#243;w

ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków Problem A: Rubik's RectangleProblem B: What does the fox say?Problem C: Magical GCDProblem D: SubwayProblem E: EscapeProblem F: DraughtsProblem G: History courseProblem H: C

2018 ICPC Asia Jakarta Regional Contest

题目传送门 题号 A B C D E F G H I J K L 状态 Ο . . Ο . . . . Ο . . Ο Ο:当场 Ø:已补 .  :  待补 A. Edit Distance Thinking:kk pai爷 Code:kk 不能直接反转,比如"010101",直接反转后就变成"101010",右移一位,然后加个0就可以了. 所以要先统计01的数量,如果0大于1,就全变成1,1大于0,就全变成0(从数量上的改变就大于s/2了),相等的话,就看首位是0

2019-2020 ICPC, Asia Jakarta Regional Contest H. Twin Buildings

As you might already know, space has always been a problem in ICPC Jakarta. To cope with this, ICPC Jakarta is planning to build two new buildings. These buildings should have a shape of a rectangle of the same size. Now, their problem is to find lan

The 2018 ACM-ICPC Asia Qingdao Regional Contest K XOR Clique

K XOR Clique BaoBao has a sequence a?1??,a?2??,...,a?n??. He would like to find a subset S of {1,2,...,n} such that ?i,j∈S, a?i??⊕a?j??<min(a?i??,a?j??) and ∣S∣ is maximum, where ⊕ means bitwise exclusive or. Input There are multiple test cases. The

2018-2019 ACM-ICPC, Asia Seoul Regional Contest

ProblemA Circuits Solved. 题意: 有$n$个矩形,可以放两条平行与$x$轴的线,求怎么放置两条无线长的平行于$x$轴的线,使得他们与矩形相交个数最多 如果一个矩形同时与两条线相交,只算一次. 思路: 离散化后枚举一根线,另一根线用线段树维护,扫描线思想 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 400010 5 int n; 6 int b[N]; 7 int x[N], y[N];

2019-2020 ICPC, Asia Jakarta Regional Contest C. Even Path

Pathfinding is a task of finding a route between two points. It often appears in many problems. For example, in a GPS navigation software where a driver can query for a suggested route, or in a robot motion planning where it should find a valid seque

2014 ACM/ICPC Asia Regional Guangzhou Online Wang Xifeng&#39;s Little Plot HDU5024

一道好枚举+模拟题目.转换思维视角 这道题是我做的,规模不大N<=100,以为正常DFS搜索,于是傻乎乎的写了起来.各种条件限制模拟过程 但仔细一分析发现对每个点进行全部八个方向的遍历100X100X100^8 .100X100个点,每个点在走的时候8中选择,TLE 于是改为另一个角度: 以符合要求的点为拐弯点,朝两个垂直的方向走,求出最远的距离.这样只要对每个点各个方向的长度知道,组合一下对应的就OK. 避免了每个点深搜. PS:搜索的时候x,y写反了,导致构图出现问题,以后用[dy][dx]

HDU 5014 Number Sequence(2014 ACM/ICPC Asia Regional Xi&#39;an Online) 题解

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5014 Number Sequence Problem Description There is a special number sequence which has n+1 integers. For each number in sequence, we have two rules: ● ai ∈ [0,n] ● ai ≠ aj( i ≠ j ) For sequence a and sequ