uvalive 3713 Astronauts
题意:
现在要安排一些宇航员去星球勘探。有3个星球,分别是J第一大的月亮A,J第二大的月亮B,S第一大的月亮C。
规定年轻的宇航员不能去A,年长的宇航员不能去B,C任何人都可以去。
现在有一些宇航员之间有矛盾,他们不能去相同的星球。
现在问可否安排出这样的方案满足条件,如果有,那么就输出每个宇航员去的星球,没有就说明不可能。
思路:
2-SAT问题
对于年轻的宇航员,去B为真,去C为假
对于年长的宇航员,去A为真,去C为假
首先考虑对于不同类型的宇航员i和j,只要他们不在同一个星球C上就满足条件,即Xi ∨ Xj为真就满足,利用这个条件加边
但是对于同一个类型的宇航员i和j,他们不在同一个星球才满足条件,这个条件要求Xi 和Xj当中必定一个为真,一个为假,那么如何刻画呢?那就是两个当中至少一个为真,至少有一个为假,用符号表示即为Xi V Xj,┐Xi ∨┐Xj 两个条件同时为真,那么进行两次加边就可以了。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <vector> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn = 100005; 9 int a[maxn]; 10 11 struct twosat 12 { 13 int n; 14 vector<int> g[maxn*2]; 15 bool mark[maxn*2]; 16 int s[maxn*2],c; 17 18 bool dfs(int x) 19 { 20 if (mark[x^1]) return false; 21 if (mark[x]) return true; 22 23 mark[x] = true; 24 25 s[c++] = x; 26 27 for (int i = 0;i < g[x].size();i++) 28 { 29 if (!dfs(g[x][i])) return false; 30 } 31 32 return true; 33 } 34 35 void init(int n) 36 { 37 this -> n = n; 38 39 for (int i = 0;i <= n * 2;i++) g[i].clear(); 40 41 memset(mark,0,sizeof(mark)); 42 } 43 44 void add_clause(int x,int xval,int y,int yval) 45 { 46 x = 2 * x + xval; 47 y = 2 * y + yval; 48 49 g[x^1].push_back(y); 50 g[y^1].push_back(x); 51 } 52 53 bool solve() 54 { 55 for (int i = 0;i < 2 * n;i += 2) 56 { 57 if (!mark[i] && !mark[i+1]) 58 { 59 c = 0; 60 61 if (!dfs(i)) 62 { 63 while (c > 0) mark[s[--c]] = 0; 64 65 if (!dfs(i+1)) return false; 66 } 67 } 68 } 69 70 return true; 71 } 72 } twosat; 73 74 int main() 75 { 76 int n,m; 77 //int kase = 0; 78 79 while (scanf("%d%d",&n,&m) != EOF) 80 { 81 if (n == 0 && m == 0) break; 82 83 int ave = 0; 84 85 for (int i = 0;i < n;i++) 86 { 87 scanf("%d",&a[i]); 88 ave += a[i]; 89 } 90 91 //ave /= n; 92 93 twosat.init(n); 94 95 for (int i = 0;i < m;i++) 96 { 97 int x,y; 98 99 scanf("%d%d",&x,&y); 100 101 x--,y--; 102 103 //if (x == y) continue; 104 105 if (a[x] * n < ave && a[y] * n < ave) 106 { 107 twosat.add_clause(x,1,y,1); 108 twosat.add_clause(x,0,y,0); 109 } 110 else if (a[x] * n >= ave && a[y] * n >= ave) 111 { 112 twosat.add_clause(x,1,y,1); 113 twosat.add_clause(x,0,y,0); 114 } 115 else 116 { 117 twosat.add_clause(x,1,y,1); 118 } 119 } 120 121 if (twosat.solve()) 122 { 123 for (int i = 0;i < n;i++) 124 { 125 if (a[i] * n >= ave) 126 { 127 if (twosat.mark[2*i+1]) printf("A\n"); 128 else printf("C\n"); 129 } 130 else 131 { 132 if (twosat.mark[2*i+1]) printf("B\n"); 133 else printf("C\n"); 134 } 135 } 136 } 137 else 138 { 139 printf("No solution.\n"); 140 } 141 142 //printf("\n"); 143 } 144 145 return 0; 146 }
转载于:https://www.cnblogs.com/kickit/p/8809207.html
uvalive 3713 Astronauts相关推荐
- 训练指南 UVALive - 3713 (2-SAT)
layout: post title: 训练指南 UVALive - 3713 (2-SAT) author: "luowentaoaa" catalog: true mathja ...
- uvaLive 3713
题目链接 #include <cstdio> #include <cstring> #include <vector> using namespace std; # ...
- uvalive 3713 2-sat
/** 分析:训练指南图论例题10,p327 2-sat **/#include <iostream> #include <cstdio> #include <cstri ...
- 图论算法与模型(训练指南题库)
一.基础题目 1.UVA 11624 Fire!迷宫问题 多源BFS 题意: 帮助joe走出一个大火蔓延的迷宫,其中joe每分钟可往上下左右四个方向之一走,所有着火的格子都会蔓延(空格与着火格有公共边 ...
- DP UVALive 6506 Padovan Sequence
题目传送门 /*题意:两行数字,相邻列一上一下,或者隔一列两行都可以,从左到右选择数字使和最大DP:状态转移方程:dp[i][j] = max (dp[i][j], dp[1-i][j-1] + a[ ...
- The UVALIVE 7716 二维区间第k小
The UVALIVE 7716 二维区间第k小 /** 题意:给一个n * n的矩阵,有q个查询每次查询r,c,s,k表示已(r,c)为右上角 大小为s的正方形中 第k小的元素n <= 250 ...
- UVALive 8513 lovers 2017 西安区域赛 B 贪心+multiset
UVALive 8513 有2种人,每个人有自己的权值$A_i$ $B_i$ 当$A_i + B_i >=K$时 两个人可以配对 问最多多少人可以配对 解法 : 把$/{ A_i /}$ 排序 ...
- 逆序数 UVALive 6508 Permutation Graphs
题目传送门 1 /* 2 题意:给了两行的数字,相同的数字连线,问中间交点的个数 3 逆序数:第一行保存每个数字的位置,第二行保存该数字在第一行的位置,接下来就是对它求逆序数 4 用归并排序或线段树求 ...
- Infinite Fraction Path UVALive - 8207
Infinite Fraction Path UVALive - 8207 题意: 给你n个数,每个数在0到9之间,每个数的下标一次是0~n-1,然后他所能走到的数为(i^2+1)%n,i为他本身的下 ...
- F - Heron and His Triangle UVALive - 8206
F - Heron and His Triangle UVALive - 8206 题意: 给你应该n,然后求一个最小的t,问长度为t-1,t,t+1所组成的三角形的面积为整数,t>=n 题解: ...
最新文章
- Spring的控制反转(IOC)和依赖注入(DI)具体解释
- yolov3-tf2 数据格式压缩
- Hadoop 面试题之Hbase
- stand up meeting 12/8/2015
- 微服务~Eureka实现的服务注册与发现及服务之间的调用
- pycharm中无法识别相对路径的问题
- 单片机片外程序存储器数据存储器操作命令
- 支付宝最不想看到的:当“集五福”变成赚钱生意 有人日入千元!
- python语言磁力搜索引擎源码公开,基于DHT协议,十二分有技术含量的技术博客...
- mysql查询,left join(求并集),where(求交集)
- 基于html5的网上订餐系统,基于WEB的网上订餐系统-任务书.doc
- Vue中<keep-alive>组件的使用
- UDP进程terminated
- 基于matlab的车牌定位算法设计与实现,原创】基于matlab的汽车牌照识别系统设计与实现...
- MAC下微信双开(一键命令)
- 怎么制作书单视频?一款好用的制作软件教程
- [论文阅读笔记14]Nested named entity recognition revisited
- 开源项目:BottomBar
- 1325208-25-0,Mal-PEG4-NHS马来酰亚胺基团和NHS酯基团交联剂
- CDN里面的一些名词你知道是什么意思吗?