URAL 1128 Partition into Groups
2015-12-07 01:26
423 查看
http://acm.timus.ru/problem.aspx?space=1&num=1128
问是否能把他们分成两组,使得这N个小朋友最多只有一个敌对小朋友在一组
然后每次选择一个不满足题意的小朋友x,把x放到另一组,不断重复操作。
则算法必能在有限步内结束,并必有解。
证明:
x不满足题意,则他有至少两个敌对小朋友。
此时把他放到另一组,至少会减少两对敌对关系,至多在另一边增加一对敌对关系,
则总敌对关系数至少会减少1,
故有限步数后,能得到满足题意的解。
题意
N个小朋友,每个小朋友最多有3个敌对小朋友,问是否能把他们分成两组,使得这N个小朋友最多只有一个敌对小朋友在一组
题解
首先把所有小朋友分到一组,然后每次选择一个不满足题意的小朋友x,把x放到另一组,不断重复操作。
则算法必能在有限步内结束,并必有解。
证明:
x不满足题意,则他有至少两个敌对小朋友。
此时把他放到另一组,至少会减少两对敌对关系,至多在另一边增加一对敌对关系,
则总敌对关系数至少会减少1,
故有限步数后,能得到满足题意的解。
code
#include <algorithm> #include <bitset> #include <cassert> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <iostream> #include <map> #include <queue> #include <set> #include <string> #include <vector> const int maxn = 10010; const int maxm = 30010; int st[maxn], lk[maxm], b[maxm], ok[maxm]; int tot; void addedge(int u, int v) { lk[++ tot] = st[u]; b[tot] = v; ok[tot] = 1; st[u] = tot; } int col[maxn]; int Q[1000000]; int l, r; bool inq[maxn]; int ans1[maxn], ans1_N; int ans2[maxn], ans2_N; int n; void solve() { scanf("%d", &n); tot = 1; memset(st, 0, sizeof st); for (int u = 1; u <= n; ++ u) { int x; scanf("%d", &x); while (x --) { int v; scanf("%d", &v); addedge(u, v); } } for (int u = 1; u <= n; ++ u) col[u] = 1; l = r = 0; for (int u = 1; u <= n; ++ u) { Q[r ++] = u; inq[u] = 1; } for (; l != r; ++ l) { int u = Q[l], cnt = 0; inq[u] = 0; for (int i = st[u]; i; i = lk[i]) { int v = b[i]; if (col[v] == col[u]) ++ cnt; } if (cnt > 1) { col[u] = 3 - col[u]; for (int i = st[u]; i; i = lk[i]) { int v = b[i]; if (!inq[v]) { if (r < 1000000) Q[r ++] = v; } } } } for (int u = 1; u <= n; ++ u) if (col[u] == 1) ans1[ans1_N ++] = u; else ans2[ans2_N ++] = u; if (ans1_N < ans2_N || (ans1_N == ans2_N && col[1] == 1)) { printf("%d\n", ans1_N); for (int i = 0; i < ans1_N; ++ i) printf("%d%c", ans1[i], i == ans1_N-1 ? '\n' : ' '); } else { printf("%d\n", ans2_N); for (int i = 0; i < ans2_N; ++ i) printf("%d%c", ans2[i], i == ans2_N-1 ? '\n' : ' '); } } int main() { // freopen("E.in", "r", stdin); solve(); // for(;;); return 0; }
相关文章推荐
- 简单的四则运算
- 数的奇偶性
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- 矩阵的乘法操作
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置
- 杭电题目---一只小蜜蜂
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1002
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points