• 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
    */
  • 相关阅读:
    Abp Zero 演示(链接)
    阿里中台战略是个伪命题(转)
    AlphaFlow智能BPM专家的博客
    绵绵用力方能久久为功 --《工程建设企业管理信息化实用案例精选》前言 -- 鲁贵卿
    业务梳理优化(政府、企业)---- 收集网上资料链接
    .NET for Apache® Spark™ 开源大数据分析工具
    Net Core 3.0 及 AspNet 3.0
    统一身份访问管理平台 (收集)-- Identity Access management platform
    SciSharp .Net 平台的人工智能,Net 如何调用 Python
    Identity Server4 及 其它 OpenId 服务器 学习
  • 原文地址:https://www.cnblogs.com/mountaink/p/11615502.html
Copyright © 2020-2023  润新知