题意:有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的更多相关文章

  1. 【UVALive - 3713】Astronauts (2-SAT)

    题意: 有n个宇航员,按照年龄划分,年龄低于平均年龄的是年轻宇航员,而年龄大于等于平均年龄的是老练的宇航员. 现在要分配他们去A,B,C三个空间站,其中A站只有老练的宇航员才能去,而B站是只有年轻的才 ...

  2. UVA 3713 Astronauts

    The Bandulu Space Agency (BSA) has plans for the following three space missions: • Mission A: Landin ...

  3. UVALive - 3713 - Astronauts(图论——2-SAT)

    Problem   UVALive - 3713 - Astronauts Time Limit: 3000 mSec Problem Description Input The input cont ...

  4. UVa 1391 Astronauts (2SAT)

    题意:给出一些宇航员他们的年龄,x是他们的平均年龄,其中A任务只能给年龄大于等于x的人,B任务只能给小于x的人,C任务没有限制.再给出m对人,他们不能同任务.现在要你输出一组符合要求的任务安排. 思路 ...

  5. UVALive 3713 Astronauts (2-SAT,变形)

    题意: 有A,B,C三种任务,每个人必获得1个任务,大于等于平均年龄的可以选择A和C,小于平均年龄的可以选择B和C.这些人有一些是互相讨厌的,必须不能执行同任务,问能否安排他们工作?若行,输出任意一组 ...

  6. UVALive - 3713 Astronauts

    给定n个宇航员的年龄,平均年龄为 ave,根据下列要求分配任务: B任务只能分配给年龄<ave的宇航员: A任务只能分配给年龄>=ave的宇航员: C任务可以任意分配. 给定m组互相憎恨的 ...

  7. uva 1391 Astronauts(2-SAT)

    /*翻译好题意 n个变量 不超过m*2句话*/ #include<iostream> #include<cstdio> #include<cstring> #inc ...

  8. UVAlive3713 Astronauts(2-SAT)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18511 [思路] 2-SAT. 设分得A或B类任务为1 C类任务为 ...

  9. uva1391 2-SAT 问题

    题意在大白书上. 有3 种工作 abc 大于等于平均年龄的可以去做a c 工作, 小于平均年龄的可以去做 bc , 同样转化为2 -sat 去做, 因为对于每个人也只有2 种情况可以作为选择 #inc ...

随机推荐

  1. 快速搭建Bootstrap

    粘贴下面代码,快速开启Bootstrap的搭建: <!DOCTYPE html> <html lang="en"> <head> <met ...

  2. 初识OpenCV-Python - 003:Mouse as a paint-brush

    此次学习了如何在OpenCV中使用鼠标事件.主要使用cv2.setMouseCallback()函数来调用鼠标事件. 首先,鼠标有如下事件: >>> import cv2>&g ...

  3. printk 函数消息是如何记录的

    printk 函数将消息写入一个   LOG_BUF_LEN 字节长的环形缓存, 长度值从 4 KB 到 1 MB, 由配置内核时选择. 这个函数接着唤醒任何在等待消息的进程, 就是说, 任何在系统 ...

  4. 16进制与utf-8

    很多人将数据的存储.传输方式和展现形式混为一谈. 类似的16进制 2进制是讲内容在电脑里面的存储或者传输的一种格式, 而utf-8 gb2312 等是输出的展现的一种格式 不是一回事,另外 gbk包含 ...

  5. 【默默努力】vue-pc-app

    最近在github上面看到了一个团队的项目,真的非常赞.他们进行vue-cli的二次开发,将项目用自己的方式打包. 今天的这个开源项目地址为:https://github.com/tffe-team/ ...

  6. Widget Factory

    Widget Factory 有N种零件,生产所需天数都为3~9天,有M条记录,记录开工星期几,和停工星期几,并告诉你这条记录所加工的零件,求每种零件的生产时间,\(1≤N,M≤300\). 解 显然 ...

  7. ThinkPHP模型基础类提供的连贯操作方法

    ThinkPHP模型基础类提供的连贯操作方法(也有些框架称之为链式操作),可以有效的提高数据存取的代码清晰度和开发效率,并且支持所有的CURD操作. 直线电机哪家好 使用也比较简单, 假如我们现在要查 ...

  8. 工作中遇到的bug

    1. Error: No PostCSS Config found in.. 在项目根目录新建postcss.config.js文件,并对postcss进行配置: module.exports = { ...

  9. Cesium官方教程10--高级粒子特效

    原文地址:https://cesiumjs.org/tutorials/Particle-Systems-More-Effects-Tutorial/ 高级粒子系统特效 这篇教程学习更多的效果,包括天 ...

  10. python面向对象应用-1

    #猫 定义类 class Cat: type = '猫' #通过__init__初始化的特征 def __init__(self,nickname,age,color): self.nickname ...