如果要相邻两个数(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. Python创建虚拟环境

    用于创建和管理虚拟环境的模块称为 venv.venv 通常会安装你可用的最新版本的 Python.如果您的系统上有多个版本的 Python,您可以通过运行 python3 或您想要的任何版本来选择特定 ...

  2. C++ 学习笔记 变量和基本类型(一)

    C++ 学习笔记 一.变量和基本类型概述 类型是所有程序的基础.类型告诉我们数据代表什么意思以及可以对数据执行哪些操作. c++基本类型: 字符型 整型 浮点型 c++ 还提供了可用于自定义数据类型的 ...

  3. PLSQL函数,存储过程

    --创建一个函数,用来根据部门编号返回调薪幅度 create or replace function get_ratio_by_dept(deptno varchar2) return number ...

  4. Intellij IDEA创建maven项目无java文件问题

    在idea开发工具中创建工程时,点击右键没有创建包.接口.java类的提示, 如图: 解决之前的项目目录为: 针对这种情况,对idea开发工具做以下设置. 选择File->Project Str ...

  5. python3去除字符串中括号及括号里面的内容

    a = """ <option value="search-alias=arts-crafts-intl-ship">Arts & ...

  6. Task 6.3 场景调研

    1.背景: (1)典型用户:信息1303班王银凤 (2)用户的需求/迫切需要解决的问题:她们宿舍上网一直使用的是外网,一年400的一种“套餐”.这种是按小时计算的,在校的时间平均下来一天可以用7 . ...

  7. Android笔记-1

    1.点击按钮出现小窗口(响应事件) 配置方式: Activity_main.xml文件中:<Button (输入)android: onClick=”test1” /> MainActiv ...

  8. TCP 连接管理

    实验代码和内容:https://github.com/ZCplayground/Understanding-Unix-Linux-Programming/tree/master/11.socket 明 ...

  9. Gradle入门(1):安装

    在Ubuntu下,执行以下命令: sudo apt-get install gradle 安装完成后,执行命令: gradle -v 得到以下信息: Picked up _JAVA_OPTIONS:  ...

  10. 守护线程(Daemon Thread)

    在Java中有两类线程:用户线程 (User Thread).守护线程 (Daemon Thread). 所谓守护 线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称 ...