题意:有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. USACO 2003 Fall Orange Cow Exhibition /// 负数01背包 oj22829

    题目大意: 输入n 接下来n行 每行输入 a b 输出n行中 a+b总和最大的同时满足 所有a总和>=0所有b总和>=0的值 负数的01背包应该反过来 w[i]为正数时 需要从大往小推 即 ...

  2. Python学习之文件操作(二)

    CSV文件处理 在Python中处理CSV文件可以使用模块csv.有关csv模块的官方资料看这里. 1 读取csv文件 csv.reader(csvfile, dialect='excel', **f ...

  3. csps模拟67神炎皇,降雷皇,幻魔皇题解

    题面:https://www.cnblogs.com/Juve/articles/11648975.html 神炎皇: 打表找规律?和$\phi$有关? 答案就是$\sum\limits_{i=2}^ ...

  4. springMVC项目创建及导入包项

    springMVC项目创建及导入包项 - zhangzhetaojj的博客 - CSDN博客https://blog.csdn.net/zhangzhetaojj/article/details/50 ...

  5. windows环境下运行Elasticsearch

    1.Elasticsearch下载地址:https://github.com/medcl/elasticsearch-rtf 直接下载ZIP包: 2.配置JAVA环境 jdk64位地址:jdk-win ...

  6. java基础之DateFormat类

    DateFormat DateFormat类概述 DateFormat 是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间. 是抽象类,所以使用其子类SimpleDateFor ...

  7. Pandas对于CSV的简单操作

    Pandas对于CSV的简单操作 最近在研究pandas对于csv文件的读取以及一些操作,网上的信息比较乱,写篇博客记录一下,毕竟自己写的才是最适合自己的用法. 首先我们应该都知道,pandas是一个 ...

  8. 编写函数处理user_list,新方法

    写函数,完成以下功能: # 例如有: user_list=[ {"name": "alex","hobby":"抽烟"} ...

  9. 轻量级IoC框架Ninject.NET搭建

    说在之前的话 IOC的概念相信大家比较熟悉了,习惯性称之为依赖注入或控制反转,园子里对基于MVC平台IOC设计模式已经相当多了,但大家都只知道应该怎么应用一个IOC模式,比如Ninject, Unit ...

  10. nginx+supervisor 前后端分离项目的发布流程

    [第一部分] 前端发布(vue项目),假设项目名为demo_vue Step1:编译打包前端项目 cd到demo_vue目录下, 执行cnpm run build:prod命令,生成disc文件夹 S ...