Problem   UVALive - 3713 - Astronauts

Time Limit: 3000 mSec

Problem Description

Input

The input contains several blocks of test cases. Each case begins with a line containing two integers 1 ≤ n ≤ 100000 and 1 ≤ m ≤ 100000. The number n is the number of astronauts. The next n lines specify the age of the n astronauts; each line contains a single integer number between 0 and 200. The next m lines contains two integers each, separated by a space. A line containing i and j (1 ≤ i,j ≤ n) means that the i-th astronaut and the j-th astronaut hate each other. The input is terminated by a block with n = m = 0.

Output

For each test case, you have to output n lines, each containing a single letter. This letter is either ‘A’, ‘B’, or ‘C’. The i-th line describes which mission the i-th astronaut is assigned to. Astronauts that hate each other should not be assigned to the same mission, only young astronauts should be assigned to Mission B and only senior astronauts should be assigned to Mission A. If there is no such assignment, then output the single line ‘No solution.’ (without quotes).

Sample Input

16 20 21 22 23 24 25 26 27 28 101 102 103 104 105 106 107 108 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 10 2 9 3 12 4 11 5 14 6 13 7 16 8 15 1 12 1 13 3 16 6 15 0 0

Sample Output

B C C B C B C B A C C A C A C A

题解:几乎是2-SAT板子题,节点之间的关系稍微复杂了一点,总体来说并不困难。两种人,老年人只能做A,C,年轻人只能做B,C,所以每种人分别对应两种人格(其实就是true和false)如果相互厌恶的两人同类,那么不能同为true,也不能同为false,如果不同类,就只需不同为false(对应C)即可,至于输出方案,mark数组就是答案。

  1 #include <bits/stdc++.h>
  2
  3 using namespace std;
  4
  5 #define REP(i, n) for (int i = 1; i <= (n); i++)
  6 #define sqr(x) ((x) * (x))
  7
  8 const int maxn = 100000 + 100;
  9 const int maxm = 30 + 10;
 10 const int maxs = 10000 + 10;
 11
 12 typedef long long LL;
 13 typedef pair<int, int> pii;
 14 typedef pair<double, double> pdd;
 15
 16 const LL unit = 1LL;
 17 const int INF = 0x3f3f3f3f;
 18 const LL mod = 1000000007;
 19 const double eps = 1e-14;
 20 const double inf = 1e15;
 21 const double pi = acos(-1.0);
 22
 23 struct TwoSAT
 24 {
 25     int n, mark[maxn * 2];
 26     vector<int> G[maxn * 2];
 27     int S[maxn * 2], c;
 28
 29     void init(int n)
 30     {
 31         this->n = n;
 32         memset(mark, 0, sizeof(mark));
 33         for (int i = 0; i < 2 * n; i++)
 34         {
 35             G[i].clear();
 36         }
 37     }
 38
 39     bool dfs(int x)
 40     {
 41         if (mark[x ^ 1])
 42             return false;
 43         if (mark[x])
 44             return true;
 45
 46         mark[x] = true;
 47         S[c++] = x;
 48         for (auto v : G[x])
 49         {
 50             if (!dfs(v))
 51                 return false;
 52         }
 53         return true;
 54     }
 55
 56     bool solve()
 57     {
 58         for (int i = 0; i < 2 * n; i += 2)
 59         {
 60             if (!mark[i] && !mark[i + 1])
 61             {
 62                 c = 0;
 63                 if (!dfs(i))
 64                 {
 65                     while (c > 0)
 66                     {
 67                         mark[S[--c]] = 0;
 68                     }
 69                     if (!dfs(i + 1))
 70                         return false;
 71                 }
 72             }
 73         }
 74         return true;
 75     }
 76
 77     void add_clause(int x, int xval, int y, int yval)
 78     {
 79         x = x * 2 + xval;
 80         y = y * 2 + yval;
 81         G[x ^ 1].push_back(y);
 82         G[y ^ 1].push_back(x);
 83     }
 84 };
 85
 86 int n, m, sum;
 87 int age[maxn];
 88 TwoSAT solver;
 89
 90 bool is_young(int x)
 91 {
 92     return x * n < sum;
 93 }
 94
 95 main()
 96 {
 97     ios::sync_with_stdio(false);
 98     cin.tie(0);
 99     //freopen("input.txt", "r", stdin);
100     //freopen("output.txt", "w", stdout);
101     while (cin >> n >> m && (n || m))
102     {
103         solver.init(n);
104         sum = 0;
105         for (int i = 0; i < n; i++)
106         {
107             cin >> age[i];
108             sum += age[i];
109         }
110         int u, v;
111         for (int i = 0; i < m; i++)
112         {
113             cin >> u >> v;
114             if (u == v)
115                 continue;
116             u--, v--;
117             if (is_young(age[u]) == is_young(age[v]))
118             {
119                 solver.add_clause(u, 0, v, 0);
120                 solver.add_clause(u, 1, v, 1);
121             }
122             else
123             {
124                 solver.add_clause(u, 1, v, 1);
125             }
126         }
127         if (solver.solve())
128         {
129             for (int i = 0; i < 2 * n; i += 2)
130             {
131                 int a = age[i / 2];
132                 if (a * n >= sum)
133                 {
134                     if (solver.mark[i])
135                     {
136                         cout << "C" << endl;
137                     }
138                     else
139                     {
140                         cout << "A" << endl;
141                     }
142                 }
143                 else
144                 {
145                     if (solver.mark[i])
146                     {
147                         cout << "C" << endl;
148                     }
149                     else
150                     {
151                         cout << "B" << endl;
152                     }
153                 }
154             }
155         }
156         else
157         {
158             cout << "No solution." << endl;
159         }
160     }
161     return 0;
162 }

转载于:https://www.cnblogs.com/npugen/p/10753205.html

UVALive - 3713 - Astronauts(图论——2-SAT)相关推荐

  1. 训练指南 UVALive - 3713 (2-SAT)

    layout: post title: 训练指南 UVALive - 3713 (2-SAT) author: "luowentaoaa" catalog: true mathja ...

  2. uvalive 3713 2-sat

    /** 分析:训练指南图论例题10,p327 2-sat **/#include <iostream> #include <cstdio> #include <cstri ...

  3. uvaLive 3713

    题目链接 #include <cstdio> #include <cstring> #include <vector> using namespace std; # ...

  4. 图论算法与模型(训练指南题库)

    一.基础题目 1.UVA 11624 Fire!迷宫问题 多源BFS 题意: 帮助joe走出一个大火蔓延的迷宫,其中joe每分钟可往上下左右四个方向之一走,所有着火的格子都会蔓延(空格与着火格有公共边 ...

  5. 计算机学院 图论方向,成电计算机学院本科生在计算机科学理论方向重要国际会议SAT上发表论文...

    近日,计算机科学与工程学院(网络空间安全学院)2017级本科生和肖鸣宇教授撰写的论文"A Fast Algorithm for SAT in Terms of Formula Length& ...

  6. UVA1391 Astronauts(ACM - ICPC 2006 Europe - Central)(2 - SAT问题、输出方案)

    虽然题目里有A.B.C三种状态,但是每个人只有两个状态可以选择,显然是一道2-SAT: 建图的话,假设选择A(或者B)为i+n,选择C为i:首先当两个人讨厌时,一个人选C,则另一个一定选另一个,连两条 ...

  7. 训练指南 UVALive - 4043(二分图匹配 + KM算法)

    layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true ...

  8. 图论专题-学习笔记:强连通分量

    图论专题-学习笔记:强连通分量 一些 update 1. 前言 2. 定义 3. 求法 4. 应用 5. 总结 一些 update update on 2021/8/12:增加了对于 Kosaraju ...

  9. DP UVALive 6506 Padovan Sequence

    题目传送门 /*题意:两行数字,相邻列一上一下,或者隔一列两行都可以,从左到右选择数字使和最大DP:状态转移方程:dp[i][j] = max (dp[i][j], dp[1-i][j-1] + a[ ...

  10. 一笔画问题【数据结构-图论】

    回家路上听到2个人在说:田字怎么一笔写成,并且笔划不重复. 田 我回家想了许久,觉得无论如何走正常的途径肯定是不行的,投机取巧脑筋急转弯的我不讨论. 那么是否可以找到数学定理? 其实就是欧拉七桥问题: ...

最新文章

  1. 【JOURNAL】恭喜发财
  2. 分布式检索系统的简单设计
  3. MIPI related
  4. discuzx2.5添加自定义积分日志
  5. spring整合mybatis接口无法注入问题
  6. 前端面试常考题:JS垃圾回收机制
  7. redis-shake简介
  8. iOS 开发之解析url中的参数
  9. [转载]网页栅格系统研究(1):960的秘密
  10. 读写卡测试程序VFP源代码
  11. 微信好友只有昵称没有微信号_只知道昵称怎么查他的微信号
  12. 7z和winrar命令行压缩方法
  13. Consul微服务注册与发现
  14. GPS之MTK平台代码小结以及gps协议注释
  15. 虚拟化桌面设备输入法
  16. 高通SDX12:USB3.0驱动初始化代码分析
  17. 计算广告概述【计算广告】
  18. Oracle日期函數
  19. 如何把项目改成微服务项目_微服务拆分那点事
  20. 使用O2OA(翱途)体验人力资源管理系统

热门文章

  1. Ubuntu Apt 如何使用清华源
  2. 通过mysql修改后台密码_怎么通过修改数据库修改网站后台的管理员密码?
  3. 以色列宣布启动“创世纪2”号登月计划;我国粮食生产实现“十七连丰”丨科技新闻...
  4. 老电脑换Linux系统是否会更快,旧电脑不要装Windows!Bodhi Linux系统,小巧强悍,运行更流畅...
  5. 5G网络5G技术初探
  6. 计算机休眠和睡眠省电,几步教会你笔记本睡眠和休眠有什么区别
  7. [leetcode]592. Fraction Addition and Subtraction
  8. Executing an update/delete query报错
  9. 忘记vmware虚拟机系统登入密码如何破解,破解vmware登录密码。
  10. ubuntu永久修改mac地址