UVA1391 Astronauts(LA3713)

来源:互联网 发布:ip广播软件下载 编辑:程序博客网 时间:2024/06/11 21:44

前几天一直做这道题,但是硬是没过,今天再做就A了

刘汝佳提供的代码是wrong的,但是也没找到错在哪,希望有心人找到错后提醒下在下!


每个宇航员都只对应一对A和C或者B和C,因此我们只记两个点为C和非C

对于每一对矛盾的人,一个选C另一个就只能选择非C,即C1->非C2和C2->非C1;

如果他们年龄段相同时,一个人选择非C则另一个人只能选择C,即非C1->C2和非C2->C1;(这两条边不一定有)

这样每一对矛盾都能组成两条边或者四条边

建好图以后就是典型的2-SAT问题了,用DFS来实现!

#include <stdio.h>#include <string.h>#include <vector>using namespace std;const int maxn = 100000+10;vector<int> adj[maxn*2];bool flag[maxn*2];bool eld[maxn];//true表示年龄够了int N, M, age[maxn];int myStack[maxn*2], top;//第i个人占2*i和2*i+1, 2*i表示A和B, 2*i+1表示Cvoid Init(){    for(int i = 1; i <= N; i++)    {        adj[2*i].clear(), adj[2*i+1].clear();        flag[2*i] = false, flag[2*i+1] = false;    }    int sum = 0;    for(int i = 1; i <= N; i++)    {        scanf("%d", &age[i]);        sum += age[i];    }    for(int i = 1; i <= N; i++)        if(age[i] * N < sum)//年轻            eld[i] = false;        else            eld[i] = true;        int a, b;        for(int i = 1; i <= M; i++)        {            scanf("%d%d", &a, &b);//a和b兄弟,a兄弟和b            adj[2*a+1].push_back(2*b);            adj[2*b+1].push_back(2*a);//任何一个选了c另一个只能选另一个            if(eld[a] == eld[b])//若年龄段相同            {                adj[2*a].push_back(2*b+1);                adj[2*b].push_back(2*a+1);            }        }}bool DFS(int cur){    int sibling = cur^1;    if(flag[sibling])        return false;    if(flag[cur])        return true;    flag[cur] = true;    myStack[top++] = cur;    for(vector<int>::iterator it = adj[cur].begin(); it != adj[cur].end(); it++)        if(!DFS(*it))            return false;    return true;}void Resolve(){    while(top != 0)    {        int ans = myStack[--top];        flag[ans] = false;    }}bool Solve(){    for(int i = 1; i <= N; i++)    {        if(flag[2*i] || flag[2*i+1])            continue;        top = 0;        if(!DFS(2*i))        {            Resolve();//还原所选            if(!DFS(2*i+1))                return false;        }    }    return true;}int main(){    while(scanf("%d%d", &N, &M) != EOF && N+M)    {        Init();        if(!Solve())            printf("No solution.\n");        else        {            for(int i = 1; i <= N; i++)            {                if(flag[2*i+1])                    printf("C\n");                else if(!eld[i])//年轻                    printf("B\n");                else                    printf("A\n");            }        }    }    return 0;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 乳腺萎缩和韧带松弛怎么办 航海王启航服务器爆满怎么办 LOL记分板没了怎么办 辅导孩子做作业没有耐心怎么办 宝宝住院三天回家不吃母乳怎么办 锁频君把应用变暗了怎么办 95的油加成92的怎么办 倒库一边宽了怎么办 倒库老是倒不好怎么办 倒库方向打早了怎么办 倒库左边小了怎么办 倒车入库小于30公分怎么办 倒库大于30公分怎么办 有行车记录仪遇到碰瓷怎么办 狗换了主人不吃怎么办 遇到扔东西碰瓷怎么办 碰见碰瓷的人怎么办 开店遇上碰瓷的顾客怎么办 我刮到别人的车怎么办 新车被刮了漆怎么办 停车擦到别人车怎么办 骑自行车被汽车撞了怎么办 车停在小区被刮怎么办 机动车被自行车撞了怎么办 单车撞小车后被起诉怎么办 给小车撞到电动单车怎么办 车停在路边被自行车撞怎么办 撞了碰瓷的人怎么办 谷丙转氨酶46该怎么办 渣土车开飞机了怎么办 自己车撞自己车怎么办 撞了人没钱赔怎么办 闯红灯扣了6分怎么办 开共享汽车闯红灯了怎么办 新手如果不小心闯红灯怎么办 红绿灯左转车道直行了怎么办 跟着大车后面闯了红灯怎么办 宝宝私处好红怎么办呢 甲亢难怀孕怎么办才好 怀孕8周查出甲亢怎么办 电动车被交警拖走了怎么办