如果要相邻两个数(a[i] >= 2)相加为质数,显然它们的奇偶性不同,也就是说一个圆桌(环)必须是偶环。

也就是答案的若干个环组成了一张二分图,其中以奇偶分色。

考虑每个点的度数一定为2,用最大流解决:

  1. 让源点向所有的奇数点连流量为2的边。
  2. 让所有的偶数点向汇点连流量为2的边。
  3. 当且仅当一组奇数和偶数相加为质数时,连一条流量为1的边。

可以证明,如果最大流小于n,那就不存在解,否则一定存在若干个边数大于2的偶环,使得所有点只出现在一个环里,最后Dfs找出环即可。

$ \bigodot $ 技巧&套路:

  • 根据奇偶性或网格图黑白染色,想到建立二分图。
  • 最大流的模型。
 #include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm> const int N = , M = ; int n, s, t, tot, a[N], vis[N], lc[N], rc[N], ln, rn;
int ntp[];
std::vector<int> an[N]; void Init() {
ntp[] = ;
for (int i = ; i <= ; ++i) if (!ntp[i]) {
for (int j = i * i; j <= ; j += i) {
ntp[j] = ;
}
}
} namespace GR {
int yun = , cur[N], las[N], to[M << ], pre[M << ], fl[M << ];
int h[N], gap[N];
inline void Add(int a, int b, int c) {
to[++yun] = b; fl[yun] = c; pre[yun] = las[a]; las[a] = yun;
to[++yun] = a; fl[yun] = ; pre[yun] = las[b]; las[b] = yun;
}
int Isap(int x, int flo, int usd = ) {
if (x == t) return flo;
for (int i = cur[x]; i; i = pre[i]) if (fl[i] > && h[to[i]] + == h[x]) {
int f = Isap(to[i], std::min(flo, fl[i]));
usd += f; fl[i] -= f; fl[i ^ ] += f;
if (fl[i] > ) cur[x] = i;
if (usd == flo) return flo;
}
if (gap[h[x]] == ) h[s] = t + ;
--gap[h[x]]; ++gap[++h[x]];
cur[x] = las[x];
return usd;
}
int Max_flow(int re = ) {
memset(h, , sizeof h);
memset(gap, , sizeof gap);
for (; h[s] < t + ; ) re += Isap(s, 1e9);
return re;
}
} void Build() {
s = n + ; t = n + ;
for (int i = ; i <= n; ++i) {
if (a[i] & ) {
lc[++ln] = i; GR::Add(s, i, );
} else {
rc[++rn] = i; GR::Add(i, t, );
}
}
for (int i = ; i <= ln; ++i) {
for (int j = ; j <= rn; ++j) {
if (!ntp[a[lc[i]] + a[rc[j]]]) {
GR::Add(lc[i], rc[j], );
}
}
}
} void Dfs(int gr, int x) {
an[gr].push_back(x);
vis[x] = ;
for (int i = GR::las[x]; i; i = GR::pre[i]) {
int v = GR::to[i];
if (vis[v] || v == s || v == t) continue;
if (((~i & ) && GR::fl[i] == ) || ((i & ) && GR::fl[i] == )) {
Dfs(gr, v);
}
}
} int main() {
Init();
scanf("%d", &n);
for (int i = ; i <= n; ++i) {
scanf("%d", &a[i]);
}
Build(); int ans = GR::Max_flow();
if (ans != n) {
puts("Impossible"); return ;
}
for (int i = ; i <= n; ++i) {
if (!vis[i]) Dfs(++tot, i);
}
printf("%d\n", tot);
for (int i = ; i <= tot; ++i) {
printf("%d ", (int)an[i].size());
for (int j = ; j < (int)an[i].size(); ++j) {
printf("%d ", an[i][j]);
}
putchar('\n');
} return ;
}

【Cf #290 C】Fox And Dinner(最大流)的更多相关文章

  1. Solution -「CF 510E」Fox And Dinner

    \(\mathcal{Description}\)   Link.   给定正整数集合 \(\{a_n\}\),求一种把这些数放置在任意多个圆环上的方案,使得每个环的大小大于 \(2\) 且环上相邻两 ...

  2. Codeforces Round #290 (Div. 2) E. Fox And Dinner 网络流建模

    E. Fox And Dinner time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  3. CF510E. Fox And Dinner

    CF510E. Fox And Dinner https://codeforces.com/contest/510 分析: 由于\(a_i>2\), 相邻两个数一定一奇一偶,按奇偶建立二分图. ...

  4. [CF#290 Div.1 C]Fox And Dinner(最大流)

    题目:http://codeforces.com/contest/512/problem/C 题目大意:给你若干个数,让你分成k组,每组围成一个圆,使得相邻两个数和均为素数,且每组人数应>=3个 ...

  5. 网络流(最大流)CodeForces 512C:Fox And Dinner

    Fox Ciel is participating in a party in Prime Kingdom. There are n foxes there (include Fox Ciel). T ...

  6. CodeForces Round #290 Fox And Dinner

    而是Div2的最后一题,当时打比赛的时候还不会最大流.自己能够把它写出来然后1A还是很开心的. 题意: 有n个不小于2的整数,现在要把他们分成若干个圈.在每个圈中,数字的个数不少于3个,而且相邻的两个 ...

  7. Fox And Dinner CodeForces - 510E (最大流)

    大意: n只狐狸, 要求分成若干个环, 每个环的狐狸不少于三只, 相邻狐狸年龄和为素数. 狐狸年龄都>=2, 那么素数一定为奇数, 相邻必须是一奇一偶, 也就是一个二分图, 源点向奇数点连容量为 ...

  8. 【Cf #290 B】Fox And Jumping(dp,扩展gcd)

    根据裴蜀定理,当且仅当选出来的集合的L[i]的gcd等于1时,才能表示任何数. 考虑普通的dp,dp[i][j]表示前i个数gcd为j的最少花费,j比较大,但状态数不多,拿个map转移就好了. $ \ ...

  9. 网络流 I - Fox And Dinner CodeForces - 510E

    Fox Ciel is participating in a party in Prime Kingdom. There are n foxes there (include Fox Ciel). T ...

随机推荐

  1. beego跨域请求配置

    不说废话 在main函数前加入如下代码 func init() { //跨域设置 var FilterGateWay = func(ctx *context.Context) {ctx.Respons ...

  2. undefined和“undefined”

    说实话,它们之间的区别挺明显的,我们一般认为undefined是JavaScript提供的一个“关键字”,而“undefined”却是一个字符串,只是引号的内容和undefined一样. undefi ...

  3. Netty源码分析第6章(解码器)---->第4节: 分隔符解码器

    Netty源码分析第六章: 解码器 第四节: 分隔符解码器 基于分隔符解码器DelimiterBasedFrameDecoder, 是按照指定分隔符进行解码的解码器, 通过分隔符, 可以将二进制流拆分 ...

  4. 高可用OpenStack(Queen版)集群-14.Openstack集成Ceph准备

    参考文档: Install-guide:https://docs.openstack.org/install-guide/ OpenStack High Availability Guide:http ...

  5. noip2018 D1T3 赛道修建

    题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 mm 条赛道. C 城一共有 nn 个路口,这些路口编号为 1,2,…,n1,2,…,n,有 n-1n−1 条适合于修建赛道的双向通 ...

  6. CentOS赋予一个普通用户root权限

    http://www.linuxidc.com/Linux/2012-07/64530.htm

  7. Go Going软件需求规格说明书

    1.目标是什么,目标不包括什么? 我们软件的目标是让大学生走出校园,用最小的花费到更多的地方去,开阔视野,读万卷书再行万里路. 目标暂且不包括外校学生 2.用户和典型场景是什么? 用户:在校大学生 典 ...

  8. C#编程概述

    一个简单的c#程序 标识符 标识符是一种字符串,用来命名变量.方法.参数和许多后面将要阐述的其他程序结构. 关键字 所有C#关键字都由小写字母组成,但是.NET类型名使用Pascal大小写约定. Ma ...

  9. 【Coursera】主成分分析

    一.问题 主方向的概念是什么?为什么降低维度的方法是使方差最大化? 假设某两个特征之间成线性关系,在二维平面上的表示就是数据点呈线性分布,那么可以通过将数据在主方向上进行投影,得到一个一维的数据,这个 ...

  10. Week2-作业1——关于阅读《构建之法》第1、2、16章的疑问与感悟

    关于阅读<构建之法>第1.2.16章的疑问与感悟 术语解释: 第2章,23页 什么是代码覆盖率? ———————————————————— 在测试中的代码覆盖率是指,你运行测试用例后,走过 ...