\(\mathcal{Description}\)

  Link.

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

  \(n\le200\),\(2\le a_i\le10^4\)。

\(\mathcal{Solution}\)

  这题怎么也黑了呢 qwq……

  考虑到 \(2\le a_i\),有 \(4\le a_i+a_j\),所以素数必然是奇素数,而一个环必然是偶环。一个常见的套路是奇偶分开建对偶图,不妨设左侧奇数右侧偶数,源点 \(S\) 向所有奇数连边,容量为 \(2\)(环上与两个数相邻);奇数向与之加和为素数的偶数连边,容量为 \(1\)(环大小大于 \(2\));偶数向汇点 \(T\) 连边,容量为 \(2\)。跑最大流再根据残余网络输出方案即可。

\(\mathcal{Code}\)

#include <queue>
#include <cstdio>
#include <vector> const int MAXN = 200, MAXV = 2e4, INF = 0x3f3f3f3f;
int n, pn, oc, ec, S, T, ecnt = 1, a[MAXN + 5], pr[MAXV + 5];
int d[MAXN + 5], head[MAXN + 5], curh[MAXN + 5], ref[MAXN + 5];
bool vis[MAXV + 5], mtc[MAXN + 5];
std::vector<int> odd, even;
std::vector<std::vector<int> > table; struct Edge { int to, flow, nxt; } graph[MAXN * 2 + MAXN * MAXN / 2 + 5]; inline void link ( const int s, const int t, const int f ) {
graph[++ ecnt] = { t, f, head[s] };
head[s] = ecnt;
} inline void addEdge ( const int s, const int t, const int f ) {
link ( s, t, f ), link ( t, s, 0 );
} inline void sieve ( const int n ) {
vis[1] = true;
for ( int i = 2; i <= n; ++ i ) {
if ( ! vis[i] ) pr[++ pn] = i;
for ( int j = 1; j <= pn && i * pr[j] <= n; ++ j ) {
vis[i * pr[j]] = true;
if ( ! ( i % pr[j] ) ) break;
}
}
} inline int DFS ( const int u, int iflow ) {
if ( u == T ) return iflow;
int oflow = 0;
for ( int& i = curh[u], v, of; i; i = graph[i].nxt ) {
if ( d[v = graph[i].to] == d[u] + 1 && graph[i].flow ) {
of = DFS ( v, std::min ( iflow, graph[i].flow ) );
oflow += of, graph[i].flow -= of, graph[i ^ 1].flow += of;
if ( ! ( iflow -= of ) ) break;
}
}
if ( ! oflow ) d[u] = -1;
return oflow;
} inline bool BFS () {
static std::queue<int> que;
for ( int i = 1; i <= T; ++ i ) d[i] = -1;
que.push ( S ), d[S] = 0;
for ( int u; ! que.empty (); que.pop () ) {
u = que.front ();
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ! ~ d[v = graph[i].to] && graph[i].flow ) {
que.push ( v ), d[v] = d[u] + 1;
}
}
}
return ~ d[T];
} inline int Dinic () {
int ret = 0;
for ( ; BFS (); ret += DFS ( S, INF ) ) {
for ( int i = 1; i <= T; ++ i ) {
curh[i] = head[i];
}
}
return ret;
} inline void match ( const int u, std::vector<int>& now ) {
now.push_back ( u ), mtc[u] = true;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ! mtc[v = graph[i].to] && v < S
&& ( ( u <= oc && graph[i ^ 1].flow ) || ( u > oc && graph[i].flow ) ) ) {
match ( v, now );
break;
}
}
} int main () {
scanf ( "%d", &n );
int mx = 0;
for ( int i = 1; i <= n; ++ i ) {
scanf ( "%d", &a[i] );
if ( mx < a[i] ) mx = a[i];
if ( a[i] & 1 ) odd.push_back ( a[i] );
else even.push_back ( a[i] );
}
sieve ( mx << 1 );
oc = odd.size (), ec = even.size ();
S = oc + ec + 1, T = S + 1;
for ( int i = 1, ot = 0, ct = 0; i <= n; ++ i ) {
if ( a[i] & 1 ) ref[++ ot] = i;
else ref[oc + ++ ct] = i;
}
for ( int i = 1; i <= oc; ++ i ) addEdge ( S, i, 2 );
for ( int i = 1; i <= ec; ++ i ) addEdge ( i + oc, T, 2 );
for ( int i = 0; i ^ oc; ++ i ) {
for ( int j = 0; j ^ ec; ++ j ) {
if ( ! vis[odd[i] + even[j]] ) {
addEdge ( i + 1, oc + j + 1, 1 );
}
}
}
int f = Dinic ();
if ( f < n ) return puts ( "Impossible" ), 0;
std::vector<int> now;
for ( int i = 1; i <= oc; ++ i ) {
if ( ! mtc[i] ) {
now.clear ();
match ( i, now );
table.push_back ( now );
}
}
printf ( "%d\n", ( int ) table.size () );
for ( auto ele: table ) {
printf ( "%d", ( int ) ele.size () );
for ( int v: ele ) printf ( " %d", ref[v] );
putchar ( '\n' );
}
return 0;
}

Solution -「CF 510E」Fox And Dinner的更多相关文章

  1. Solution -「CF 1342E」Placing Rooks

    \(\mathcal{Description}\)   Link.   在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...

  2. Solution -「CF 1622F」Quadratic Set

    \(\mathscr{Description}\)   Link.   求 \(S\subseteq\{1,2,\dots,n\}\),使得 \(\prod_{i\in S}i\) 是完全平方数,并最 ...

  3. Solution -「CF 923F」Public Service

    \(\mathscr{Description}\)   Link.   给定两棵含 \(n\) 个结点的树 \(T_1=(V_1,E_1),T_2=(V_2,E_2)\),求一个双射 \(\varph ...

  4. Solution -「CF 923E」Perpetual Subtraction

    \(\mathcal{Description}\)   Link.   有一个整数 \(x\in[0,n]\),初始时以 \(p_i\) 的概率取值 \(i\).进行 \(m\) 轮变换,每次均匀随机 ...

  5. Solution -「CF 1586F」Defender of Childhood Dreams

    \(\mathcal{Description}\)   Link.   定义有向图 \(G=(V,E)\),\(|V|=n\),\(\lang u,v\rang \in E \Leftrightarr ...

  6. Solution -「CF 1237E」Balanced Binary Search Trees

    \(\mathcal{Description}\)   Link.   定义棵点权为 \(1\sim n\) 的二叉搜索树 \(T\) 是 好树,当且仅当: 除去最深的所有叶子后,\(T\) 是满的: ...

  7. Solution -「CF 623E」Transforming Sequence

    题目 题意简述   link.   有一个 \(n\) 个元素的集合,你需要进行 \(m\) 次操作.每次操作选择集合的一个非空子集,要求该集合不是已选集合的并的子集.求操作的方案数,对 \(10^9 ...

  8. Solution -「CF 1023F」Mobile Phone Network

    \(\mathcal{Description}\)   Link.   有一个 \(n\) 个结点的图,并给定 \(m_1\) 条无向带权黑边,\(m_2\) 条无向无权白边.你需要为每条白边指定边权 ...

  9. Solution -「CF 599E」Sandy and Nuts

    \(\mathcal{Description}\)   Link.   指定一棵大小为 \(n\),以 \(1\) 为根的有根树的 \(m\) 对邻接关系与 \(q\) 组 \(\text{LCA}\ ...

随机推荐

  1. Oracle 报 ORA-00054资源正忙的解决办法

    oracle之报错:ORA-00054: 资源正忙,要求指定 NOWAIT 问题如下: SQL> conn scott/tiger@vm_database Connected to Oracle ...

  2. grafana中如何展示prometheus的延迟分布数据?

    最终效果 最终在grafana中展示了一个服务每分钟的延迟分布: 各个部分的含义如下: 1.时间的分布,从0.01秒到最多720秒 2.用颜色深浅代表次数.颜色越深,请求次数越多 3.时间轴,代表在这 ...

  3. Cesium中级教程10 - CesiumJS and webpack

    Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ webpack是打包JavaScript模块流行且强大的工具.它 ...

  4. VS2017:win32项目与win32控制台应用程序的转换方法

    原文:https://www.cnblogs.com/asuser/articles/12297251.html 刚开始使用VS2017新建项目工程时,有时把应用类型的工程建成控制台类型的工程,在编译 ...

  5. golang中int、float、string数据类型之间的转换

    package main import ( "fmt" "strconv" ) func main() { var num1 int = 88 var num2 ...

  6. How to check in Windows if you are using UEFI

    You might be wondering if Windows is using UEFI or the legacy BIOS, it's easy to check. Just fire up ...

  7. Android安卓开发-记账本布局

    账单页面布局统计页面布局我的页面布局主页面加号记账页面布局.点击记账页面记账类别布局点击收入页面收入类别布局统计页面支出布局统计页面收入布局查询页面布局数据库设计字段一,支出id和收入id分配字段二, ...

  8. Java多线程专题1: 并发与并行的基础概念

    合集目录 Java多线程专题1: 并发与并行的基础概念 什么是多线程并发和并行? 并发: Concurrency 特指单核可以处理多任务, 这种机制主要实现于操作系统层面, 用于充分利用单CPU的性能 ...

  9. Abp 审计模块源码解读

    Abp 审计模块源码解读 Abp 框架为我们自带了审计日志功能,审计日志可以方便地查看每次请求接口所耗的时间,能够帮助我们快速定位到某些性能有问题的接口.除此之外,审计日志信息还包含有每次调用接口时客 ...

  10. Activity 不只有跳转。功能篇(一)

    Activity生命周期 1:activity四种启动方式 standard,SingleTask,SingleTop,SingleInstance standard:是系统默认的,每次启动该acti ...