• UVALive3713_Astronauts


    有n个宇航员,根据年龄限制,所有宇航员只能从事A或B中的一种任务,所有人都可以从事C的任务。有的宇航员之间相互讨厌,不能分在一组,求出一种满足条件的分配方案。

    2sat。mark[]中i+i和i+i+1分别表示i从事C工作或者他的特有工作。

    对于仇恨关系,我们可以知道U和V两个人不能同时从事C工作。于是加边 (U+U,V+V+1),(V+V,U+U+1)。

    同时,如果这两个人的特有工作相同,那么还需要加边(U+U+1,V+V),(V+V+1,U+U)。

    召唤代码君:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define maxn 5555550
    using namespace std;
    
    int age[maxn],n,m;
    int next[maxn],to[maxn],first[maxn],edge;
    bool mark[maxn];//0 C  1 A|B
    int Q[maxn],top;
    double avg;
    
    void addedge(int U,int V)
    {
        edge++;
        to[edge]=V,next[edge]=first[U],first[U]=edge;
    }
    
    bool dfs(int cur)
    {
        if (mark[cur^1]) return false;
        if (mark[cur]) return true;
        Q[++top]=cur,mark[cur]=true;
        for (int i=first[cur]; i!=-1; i=next[i])
            if (!dfs(to[i])) return false;
        return true;
    }
    
    int main()
    {
        int U,V;
        while (scanf("%d%d",&n,&m) && (n|m))
        {
            avg=0,edge=-1;
            for (int i=1; i<=n; i++)
            {
                scanf("%d",&age[i]);
                avg+=age[i];
                mark[i+i]=mark[i+i+1]=false;
                first[i+i]=first[i+i+1]=-1;
            }
            avg/=n;
            while (m--)
            {
                scanf("%d%d",&U,&V);
                addedge(U+U,V+V+1),addedge(V+V,U+U+1);
                if ((age[U]<avg)^(age[V]<avg)) continue;
                addedge(U+U+1,V+V),addedge(V+V+1,U+U);
            }
            bool flag=true;
            for (int i=1; i<=n; i++)
            {
                if (mark[i+i] || mark[i+i+1]) continue;
                top=0;
                if (!dfs(i+i))
                {
                    while (top) mark[Q[top--]]=false;
                    if (!dfs(i+i+1))
                    {
                        flag=false;
                        break;
                    }
                }
            }
            if (flag)
            {
                for (int i=1; i<=n; i++)
                    if (mark[i+i]) printf("C
    ");
                        else printf("%c
    ",age[i]>=avg?'A':'B');
            }
            else puts("No solution.");
        }
        return 0;
    }
  • 相关阅读:
    HQ-day17 CSS样式表基础①
    SQL 常用操作
    EXCEL 批量生成SQL
    js 顺序提交表单
    js 页面回调函数
    C# excel 常用操作
    C#关于LINQ
    JS 表单验证
    关于Cookie
    js 短信验证码功能
  • 原文地址:https://www.cnblogs.com/lochan/p/3858358.html
Copyright © 2020-2023  润新知