Fox Ciel is participating in a party in Prime Kingdom. There are n foxes there (include Fox Ciel). The i-th fox is ai years old.
They will have dinner around some round tables. You want to distribute foxes such that:
Each fox is sitting at some table.
Each table has at least 3 foxes sitting around it.
The sum of ages of any two adjacent foxes around each table should be a prime number.
If k foxes f1, f2, …, fk are sitting around table in clockwise order, then for 1 ≤ i ≤ k - 1: fi and fi + 1 are adjacent, and f1 and fk are also adjacent.
If it is possible to distribute the foxes in the desired manner, find out a way to do that.
Input
The first line contains single integer n (3 ≤ n ≤ 200): the number of foxes in this party.
The second line contains n integers ai (2 ≤ ai ≤ 104).
Output
If it is impossible to do this, output “Impossible”.
Otherwise, in the first line output an integer m (): the number of tables.
Then output m lines, each line should start with an integer k -=– the number of foxes around that table, and then k numbers — indices of fox sitting around that table in clockwise order.
If there are several possible arrangements, output any of them.
Examples
inputCopy
4
3 4 8 9
outputCopy
1
4 1 2 4 3
inputCopy
5
2 2 2 2 2
outputCopy
Impossible
inputCopy
12
2 3 4 5 6 7 8 9 10 11 12 13
outputCopy
1
12 1 2 3 6 5 12 9 8 7 10 11 4
inputCopy
24
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
outputCopy
3
6 1 2 3 6 5 4
10 7 8 9 12 15 14 13 16 11 10
8 17 18 23 22 19 20 21 24
Note
In example 1, they can sit around one table, their ages are: 3-8-9-4, adjacent sums are: 11, 17, 13 and 7, all those integers are primes.
In example 2, it is not possible: the sum of 2+2 = 4 is not a prime number.
题目大意:叫你给n个狐狸分桌,每一桌人数不少于3个,相邻的狐狸之和为质数。(圆桌)。
最后输出方案,或者说不可行。
不难想到可以用flow去做。
我们不难想到,因为是质数,所以两个数字之和为奇数,所以这两个数字一个奇数,一个偶数,所以这是一张二分图。所以奇数,偶数数量一定相同。
然后分别按照奇偶建图。现在我们要找环。我们可以知道,每个狐狸都要向左右分别连两条边。所以我们可以从源点S流出时,流量为2,每个点向汇点T流量为2.就能保证每个点连两个点了。
最后怎么找答案呢?直接从每个点dfs找环即可。(找环具体看代码,写得很简单,但是有细节)
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define endl '\n'
//#define int long long
using namespace std;
const int inf=0x3f3f3f3f;
const int N=210,M=1e5+10;
int n,a[N],vis[M],prime[M],sz;
vector<int> v[N];
int head[N],nex[M],to[M],w[M],tot=1,s,t,h[N];
inline void ade(int a,int b,int c){
to[++tot]=b; nex[tot]=head[a]; w[tot]=c; head[a]=tot;
}
inline void add(int a,int b,int c){ade(a,b,c); ade(b,a,0);}
inline int bfs(){
queue<int> q; q.push(s); memset(h,0,sizeof h); h[s]=1;
while(q.size()){
int u=q.front(); q.pop();
for(int i=head[u];i;i=nex[i]){
if(!h[to[i]]&&w[i]){
h[to[i]]=h[u]+1; q.push(to[i]);
}
}
}
return h[t];
}
int dfs(int x,int f){
if(x==t) return f; int fl=0;
for(int i=head[x];i&&f;i=nex[i]){
if(w[i]&&h[to[i]]==h[x]+1){
int mi=dfs(to[i],min(w[i],f));
w[i]-=mi,w[i^1]+=mi,fl+=mi,f-=mi;
}
}
if(!fl) h[x]=-1;
return fl;
}
inline int dinic(){
int res=0;
while(bfs()) res+=dfs(s,inf);
return res;
}
inline void get_prime(int n){
for(int i=2;i<=n;i++){
if(!prime[i]){
for(int j=i+i;j<=n;j+=i) prime[j]=1;
}
}
}
// -----找环代码-----
void dfs(int x,int fa,int flag,int k){ //k判断是奇数点,还是偶数点 ,flag判断是不是刚开始找环
if(x==fa&&flag) return ;
v[fa].push_back(x); vis[x]=1;
for(int i=head[x];i;i=nex[i]){
if(!vis[to[i]]&&w[i^k]){
dfs(to[i],fa,1,k^1); break;
}
}
}
signed main(){
ios::sync_with_stdio(false);
cin>>n; get_prime(M-5); t=n+1;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
if(a[i]&1) add(s,i,2);
else add(i,t,2);
}
for(int i=1;i<=n;i++){
if(!(a[i]&1)) continue;
for(int j=1;j<=n;j++){
if(prime[a[i]+a[j]]) continue;
add(i,j,1);
}
}
if(dinic()!=n){cout<<"Impossible"<<'\n'; return 0;}
vis[0]=vis[t]=1;
for(int i=1;i<=n;i++){
if(!(a[i]&1)) continue;
if(vis[i]) continue; dfs(i,i,0,1); sz++;
}
cout<<sz<<'\n';
for(int i=1;i<=n;i++){
if(!v[i].size()) continue;
cout<<v[i].size();
for(int j=0;j<v[i].size();j++) cout<<' '<<v[i][j];
cout<<'\n';
}
return 0;
}
来源:CSDN
作者:青烟绕指柔!
链接:https://blog.csdn.net/weixin_43826249/article/details/103734599