UVA1391/LA3713 Astronauts
题意:有A、B、C3个任务分配给n个宇航员,其中每个宇航员恰好分配一个任务。假设n个宇航员的平均年龄为x,只有年龄大于x的才能领取A任务;只有年龄严格小于x的才能领取B任务,而任务C没有限制。有m对宇航员相互讨厌,因此不能分配同一任务。求出是否能找出符合的任务方案。(转自http://blog.csdn.net/u011345461/article/details/39779721)
题目看上去是ABC三个选择,实际上每个人只有两个选择。对于每对矛盾,如果两个人选择相同(即均为BC或均为AC),那么一个选C另一个必选B(A),另一个选C一个必选B(A),一个选B(A)另一个必选C,另一个选B(A)一个必选C;如果两个人选择不同(一个AC一个BC),那么一个选C另一个必选B,另一个选C一个必选A。
这题数据范围很大,好奇nm做法是怎么水过去的。。
正解是tarjan缩点,标记每个块的对立块,建立反图,对反图top排序,对于当前的块x,删除对立块和对立块在反图上的出边,并把当前快入队。最后看队列里没被删除的块即为答案块。把点扫一扫看看在不在答案块,在的话这个点的值代表选A(B)还是选C就是这个人的选择
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <string>
#include <cmath>
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
#define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
template<class T>
inline void swap(T &a, T &b)
{
T tmp = a;a = b;b = tmp;
}
inline void read(int &x)
{
x = ;char ch = getchar(), c = ch;
while(ch < '' || ch > '') c = ch, ch = getchar();
while(ch <= '' && ch >= '') x = x * + ch - '', ch = getchar();
if(c == '-') x = -x;
}
const int INF = 0x3f3f3f3f;
const int MAXN = + ;
struct Edge
{
int u,v,nxt;
Edge(int _u, int _v, int _nxt){u = _u;v = _v;nxt = _nxt;}
Edge(){}
}edge1[MAXN << ], edge2[MAXN << ];
int head1[MAXN], head2[MAXN], vis[MAXN], tag[MAXN], rebelong[MAXN], del[MAXN], q[MAXN], he, ta, indeg[MAXN], cnt1, cnt2, n, m, belong[MAXN], group, b[MAXN], bb[MAXN], dfn[MAXN], stack[MAXN], top, low[MAXN], dfst, year[MAXN], x, tmp1, tmp2;
inline void insert1(int a, int b){edge1[++ cnt1] = Edge(a, b, head1[a]), head1[a] = cnt1;}
inline void insert2(int a, int b){edge2[++ cnt2] = Edge(a, b, head2[a]), head2[a] = cnt2;}
void dfs(int u)
{
b[u] = bb[u] = , dfn[u] = low[u] = ++ dfst, stack[++ top] = u;
for(int pos = head1[u];pos;pos = edge1[pos].nxt)
{
int v = edge1[pos].v;
if(!b[v]) dfs(v), low[u] = min(low[u], low[v]);
else if(bb[v]) low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u])
{
int now = -;++ group;
while(now != u) now = stack[top --], bb[now] = , belong[now] = group;
}
}
void rebuild()
{
memset(indeg, , sizeof(indeg)), memset(head2, , sizeof(head2));
for(int i = ;i <= cnt1;++ i)
if(belong[edge1[i].u] != belong[edge1[i].v])
insert2(belong[edge1[i].v], belong[edge1[i].u]), ++ indeg[belong[edge1[i].u]];
}
void tarjan()
{
memset(belong, , sizeof(belong)), memset(dfn, , sizeof(dfn)), memset(low, , sizeof(low)), group = , memset(b, , sizeof(b)), memset(bb, , sizeof(bb)), dfst = , top = , memset(rebelong, , sizeof(rebelong));
for(int i = ;i <= n;++ i) if(!b[i << ]) dfs(i << );
for(int i = ;i <= n;++ i) if(!b[i << | ]) dfs(i << | );
for(int i = ;i <= n;++ i) rebelong[belong[i << ]] = belong[i << | ], rebelong[belong[i << | ]] = belong[i << ];
rebuild();
}
void top_sort()
{
he = , ta = , memset(del, , sizeof(del));
for(int i = ;i <= group;++ i) if(!indeg[i]) q[ta ++] = i;
while(he < ta)
{
int now = q[he ++], renow = rebelong[now];
if(del[now]) continue; del[renow] = ;
for(int pos = head2[renow];pos;pos = edge2[pos].nxt)
{
int v = edge2[pos].v;
del[v] = ;
for(int poss = head2[v];poss;poss = edge2[poss].nxt) -- indeg[edge2[poss].v];
}
for(int pos = head2[now];pos;pos = edge2[pos].nxt)
{
int v = edge2[pos].v;
if(del[v]) continue;
-- indeg[v];
if(!indeg[v]) q[ta ++] = v;
}
}
}
int main()
{
while(scanf("%d %d", &n, &m) != EOF && n && m)
{
cnt1 = , memset(head1, , sizeof(head1)), x = ;
for(int i = ;i <= n;++ i) read(year[i]), x += year[i];
if(x % n == ) x = x / n;
else x = x / n + ;
for(int i = ;i <= n;++ i) year[i] = year[i] >= x; //year[i] = 1 表示选A或C year[i] = 0 表示选B或C
for(int i = ;i <= m;++ i)
{
read(tmp1), read(tmp2);
if(year[tmp1] == year[tmp2]) insert1(tmp1 << | , tmp2 << ), insert1(tmp2 << | , tmp1 << ), insert1(tmp1 << , tmp2 << | ), insert1(tmp2 << , tmp1 << | );
else insert1(tmp1 << | , tmp2 << ), insert1(tmp2 << | , tmp1 << );
}
tarjan();
int flag = ;
for(int i = ;i <= n;++ i) if(belong[i << | ] == belong[i << ]) flag = ;
if(flag)
{
printf("No solution.\n");
continue;
}
top_sort();
memset(vis, , sizeof(vis)), memset(tag, , sizeof(tag));
for(int i = ;i < ta;++ i) if(!del[q[i]]) vis[q[i]] = ;
for(int i = ;i <= n;++ i)
if(vis[belong[i << ]]) tag[i] = ;
else tag[i] = ;
for(int i = ;i <= n;++ i)
if(year[i] && !tag[i]) printf("A\n");
else if(!year[i] && !tag[i]) printf("B\n");
else printf("C\n");
}
return ;
}
UVA1391/LA3713
UVA1391/LA3713 Astronauts的更多相关文章
- 【UVALive - 3713】Astronauts (2-SAT)
题意: 有n个宇航员,按照年龄划分,年龄低于平均年龄的是年轻宇航员,而年龄大于等于平均年龄的是老练的宇航员. 现在要分配他们去A,B,C三个空间站,其中A站只有老练的宇航员才能去,而B站是只有年轻的才 ...
- UVA 3713 Astronauts
The Bandulu Space Agency (BSA) has plans for the following three space missions: • Mission A: Landin ...
- UVALive - 3713 - Astronauts(图论——2-SAT)
Problem UVALive - 3713 - Astronauts Time Limit: 3000 mSec Problem Description Input The input cont ...
- UVa 1391 Astronauts (2SAT)
题意:给出一些宇航员他们的年龄,x是他们的平均年龄,其中A任务只能给年龄大于等于x的人,B任务只能给小于x的人,C任务没有限制.再给出m对人,他们不能同任务.现在要你输出一组符合要求的任务安排. 思路 ...
- UVALive 3713 Astronauts (2-SAT,变形)
题意: 有A,B,C三种任务,每个人必获得1个任务,大于等于平均年龄的可以选择A和C,小于平均年龄的可以选择B和C.这些人有一些是互相讨厌的,必须不能执行同任务,问能否安排他们工作?若行,输出任意一组 ...
- UVALive - 3713 Astronauts
给定n个宇航员的年龄,平均年龄为 ave,根据下列要求分配任务: B任务只能分配给年龄<ave的宇航员: A任务只能分配给年龄>=ave的宇航员: C任务可以任意分配. 给定m组互相憎恨的 ...
- uva 1391 Astronauts(2-SAT)
/*翻译好题意 n个变量 不超过m*2句话*/ #include<iostream> #include<cstdio> #include<cstring> #inc ...
- UVAlive3713 Astronauts(2-SAT)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18511 [思路] 2-SAT. 设分得A或B类任务为1 C类任务为 ...
- uva1391 2-SAT 问题
题意在大白书上. 有3 种工作 abc 大于等于平均年龄的可以去做a c 工作, 小于平均年龄的可以去做 bc , 同样转化为2 -sat 去做, 因为对于每个人也只有2 种情况可以作为选择 #inc ...
随机推荐
- 愚人节老板发话了,免费送书 + 免费入驻Java知识星球!!
愚人节快乐,今天的活动很重磅! 1.免费送5本重量级技术书籍,不骗人,小程序随机抽奖送出哦! 2.免费进星球,哈哈不可能,愚人节快乐!不过今天有重大优惠,见下文! 活动一:免费送出5本重量级书籍 赠书 ...
- 17.splash_case02
# 抓取<我不是药神>的豆瓣评论 import csv import time import requests from lxml import etree fw = open('doub ...
- printk函数打开和关闭消息
在驱动开发的早期, printk 非常有助于调试和测试新代码. 当你正式发行驱动时, 换句 话说, 你应当去掉, 或者至少关闭, 这些打印语句. 不幸的是, 你很可能会发现, 就在你 认为你不再需要这 ...
- JS数组 呼叫团里成员(使用数组元素) myarray[0]
呼叫团里成员(使用数组元素) 我们知道数组中的每个值有一个索引号,从0开始,如下图, myarray变量存储6个人的成绩: 要得到一个数组元素的值,只需引用数组变量并提供一个索引,如: 第一个人的 ...
- leetcode-105-从前序与中序遍历构造二叉树
题目描述: 方法一: # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.va ...
- leetcode-92-反转链表②
题目描述: 方法一: class Solution: def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode: ...
- 解决CentOS“Zabbix discoverer processes 75% busy”的问题
解决CentOS“Zabbix discoverer processes 75% busy”的问题 运维 立杰 4年前 (2014-08-11) 1104℃ 0评论 在使用Zabbix过程中, ...
- 解决git每次输入密码,设置gitlab、github默认push的用户名和密码
git ssh key配置&解决git每次输入密码 欢迎加入qq群(IT-程序猿-技术交流群):757345416 在使用git时,每次pull/push都需要输入密码,有时大大降低了我们 ...
- iOS开发本地推送(iOS10)UNUserNotificationCenter
1.简介 iOS10之后苹果对推送进行了封装,UNUserNotificationCenter就这样产生了.简单介绍本地推送的使用UserNotifications官方文档说明! 2.简单使用UNUs ...
- kubeadm安装Kubernetes 1.15 实践
原地址参考github 一.环境准备(在全部设备上进行) 3 台 centos7.5 服务器,网络使用 Calico. IP地址 节点角色 CPU 内存 Hostname 10.0.1.45 mast ...