UVA 1391 - Astronauts(2-SET)

UVA 1391 - Astronauts

题目链接

题意:给定一些宇航员,年龄小于平均数能做A和C,大于等于能做B和C,现在知道一些宇航员互相憎恨,不能让他们做同一个任务,问一直种安排方法满足条件

思路:2set问题,如果两种宇航员类型相同,就两个宇航员做不一样,加一条真或真,和假或假的边,如果类型不同,就加一条真或真的边

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;

const int MAXNODE = 100005;

struct TwoSet {
	int n;
	vector<int> g[MAXNODE * 2];
	bool mark[MAXNODE * 2];
	int S[MAXNODE * 2], sn;

	void init(int tot) {
		n = tot * 2;
		for (int i = 0; i < n; i += 2) {
			g[i].clear();
			g[i^1].clear();
		}
		memset(mark, false, sizeof(mark));
	}

	void add_Edge(int u, int uval, int v, int vval) {
		u = u * 2 + uval;
		v = v * 2 + vval;
		g[u^1].push_back(v);
		g[v^1].push_back(u);
	}

	bool dfs(int u) {
		if (mark[u^1]) return false;
		if (mark[u]) return true;
		mark[u] = true;
		S[sn++] = u;
		for (int i = 0; i < g[u].size(); i++) {
			int v = g[u][i];
			if (!dfs(v)) return false;
		}
		return true;
	}

	bool solve() {
		for (int i = 0; i < n; i += 2) {
			if (!mark[i] && !mark[i + 1]) {
				sn = 0;
				if (!dfs(i)){
					for (int j = 0; j < sn; j++)
						mark[S[j]] = false;
					sn = 0;
					if (!dfs(i + 1)) return false;
				}
			}
		}
		return true;
	}
} gao;

const int N = 100005;

int n, m, age[N], sum;
vector<int> g[N];

int main() {
	while (~scanf("%d%d", &n, &m) && n) {
		sum = 0;
		gao.init(n);
		for (int i = 0; i < n; i++) {
			scanf("%d", &age[i]);
			g[i].clear();
			sum += age[i];
		}
		for (int i = 0; i < n; i++) {
			if (age[i] * n < sum)
				age[i] = 0;
			else
				age[i] = 1;
		}
		int u, v;
		while (m--) {
			scanf("%d%d", &u, &v);
			u--; v--;
			g[u].push_back(v);
		}
		for (int u = 0; u < n; u++) {
			for (int j = 0; j < g[u].size(); j++) {
				int v = g[u][j];
				if (age[u]^age[v])
					gao.add_Edge(u, 1, v, 1);
				else {
					gao.add_Edge(u, 0, v, 0);
					gao.add_Edge(u, 1, v, 1);
				}
			}
		}
		if (gao.solve()) {
			for (int i = 0; i < n; i++) {
				if (age[i] && gao.mark[i * 2 + 1]) printf("A\n");
				else if (age[i] == 0 && gao.mark[i * 2 + 1]) printf("B\n");
				else printf("C\n");
			}
		} else printf("No solution.\n");
	}
	return 0;
}
时间: 2024-12-20 02:14:45

UVA 1391 - Astronauts(2-SET)的相关文章

UVa 1391 Astronauts (2SAT)

题意:给出一些宇航员他们的年龄,x是他们的平均年龄,其中A任务只能给年龄大于等于x的人,B任务只能给小于x的人,C任务没有限制.再给出m对人,他们不能同任务.现在要你输出一组符合要求的任务安排. 思路:2SAT. 设Ai表示第i个人的任务,如果i的年龄大于等于x,那么Ai=true表示分到A任务,flase表示分到C任务.如果i年龄小于x则Ai=true表示分到B任务,flase表示分到C任务. 考虑对于这m对里的每对人,如果他们是同组的,那么(Ai并非Aj)或(非Ai并Aj)等价于 (非Ai或

uva 1391 Astronauts(2-SAT)

/*翻译好题意 n个变量 不超过m*2句话*/ #include<iostream> #include<cstdio> #include<cstring> #include<vector> #define maxn 200010 using namespace std; int n,m,f[maxn],c,s[maxn],age[maxn],sum,a,b; vector<int>G[maxn]; bool Judge(int a,int b)

UVA - 620Cellular Structure(递推)

题目:UVA - 620Cellular Structure(递推) 题目大意:只能给出三种细胞的增殖方式,然后给出最后细胞的增殖结果,最后问你这是由哪一种增殖方式得到的.如果可以由多种增殖方式得到,就输出题目中列出来的增殖方式靠前的那种. 解题思路:也是递推,细胞长度长的可以由细胞长度短的推得,并且这里第一种只能是长度为1的细胞才有可能,所以判断的时候可以3个判断,看能否与上面的增殖结果匹配,可以的话就记录下来,以后的长串就是由这样的短串再加上两个细胞继续往后推. 例如: BAABA 将A变为

UVA - 10003Cutting Sticks(递推)

题目:UVA - 10003Cutting Sticks(递推) 题目大意:给根木棍长度l,现在要锯这根木棍,给出n个锯点,求怎样锯才能使得开销最小.例如 长度为10的木棍, 锯点2 4 7,那么如果按照这个顺序 , 首先显示由长度位10的木头先锯了2 ,开销就加10,然后锯完现在有[0,2]和[2,10]长度分别为2 ,8的木棍,现在要在4这个位置锯木头,就是在长度为8的木头上锯4这个位置,这样就加上8,然后又有长度为[2,4][4,10]的木头,最后要锯7的话,就需要开销加上6.所以开销就是

UVA 10106 Product (大数相乘)

Product The Problem The problem is to multiply two integers X, Y. (0<=X,Y<10250) The Input The input will consist of a set of pairs of lines. Each line in pair contains one multiplyer. The Output For each input pair of lines the output line should c

UVA 11806 - Cheerleaders(数论+容斥原理)

题目链接:11806 - Cheerleaders 题意:在一个棋盘上,要求四周的四行必须有旗子,问有几种摆法. 思路:直接算很容易乱掉,利用容斥原理,可知AUBUCUD = |A| + |B| + |C| + |D| - |AB| - |BC| - |AC| - |AD| - |BD| - |CD| + |ABC| + |ABD| + |ACD| + |BCD| - |ABCD| 由此利用位运算去计算即可 代码: #include <stdio.h> #include <string.

UVA - 10163Storage Keepers(01背包)

题目大意:UVA - 10163Storage Keepers(01背包) 题目大意:现在有m个守店人,和n家店,每个守店人有个能力值,然后一个守护店的人可以守K家店,那么这些店能到的安全度就是Pi / K.店的安全度取决于守护它的人给的安全度中间最低的那个.这些店的最高安全度取决于最低安全度的那家店.现在问如何雇佣这些人使得店的安全度最高的情况下,费用最少. 解题思路: 安全度要求最高,那么就是要判断每个守店的人要不要雇佣,并且雇佣来之后让它守几家店(安全度).dp[i][j]表示:前面的i家

UVA - 10561 Treblecross (SG定理)

Treblecross is a two player gamewhere the goal is to get three X in a row on a one-dimensional board. At the startof the game all cells in the board is empty. In each turn a player puts a X in an empty cell, and if that results in there beingthree X

UVA 1543 - Telescope(dp+几何)

题目链接:1543 - Telescope 题意:按顺序给定圆周上一些点,问用选一些点组成m边形面积的最大值. 思路:dp,dp[i][j][k] 表示第一个点为i,最后一个点为j,当前选择k的最大值,因为多选一个点,会多的面积为他和第一个点和最后一个点构成的三角形面积,然后利用海伦公式求面积,状态转移为:dp[i][j][x] = max(dp[i][j][x], dp[i - 1][j][k] + s); 代码: #include <stdio.h> #include <string