Codeforces Round #290 (Div. 1) C. Fox And Dinner
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.
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).
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.
4
3 4 8 9
1
4 1 2 4 3
5
2 2 2 2 2
Impossible
12
2 3 4 5 6 7 8 9 10 11 12 13
1
12 1 2 3 6 5 12 9 8 7 10 11 4
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
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
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.
最大流,通过对称性质来寻找增广路径
#include <iostream> #include<stdio.h> #include<vector> #define inf 100000000 using namespace std; int b[50000],a[50000],flg[50000],dis[50000],tot,f[50000],flow,n,w[500][500],w1[500][500],pre[500]; vector<vector<int> > ans; void dog() { for(int i=1;i<=20000;i++) b[i]=0; b[1]=1; for(int i=2;i<=20000;i++) if (b[i]==0) for(int j=i+i;j<=20000;j+=i) b[j]=1; } bool bfs() { int t1,t2; for(int i=1;i<=tot;i++) dis[i]=inf; dis[1]=0; t1=0; t2=1; f[1]=1; while(true) { t1++; if (t1>t2) break; int index=f[t1]; if (index==2) break; for(int i=1;i<=2*n+2;i++) { if (dis[i]!=inf||w[index][i]<=0) continue; f[++t2]=i; dis[i]=dis[index]+1; pre[i]=index; } } if (dis[2]==inf) return false; return true; } int pig(int index) { if (index==2) return 1; if (index==1) return 2; return (index>n+2?index-n:index+n); } void findpath() { int index; index=2; while(index!=1) { //path.push_back(index); w[pre[index]][index]--; w[index][pre[index]]++; int pt1,pt2; w[pig(index)][pig(pre[index])]--; w[pig(pre[index])][pig(index)]++; index=pre[index]; } } void dfs2(int index,vector<int>& p) { flg[index]=1; p.push_back(index); for(int i=1;i<=n;i++) if (w[index+2][i+n+2]==0&&flg[i]==0&&w1[index+2][i+n+2]==1) { dfs2(i,p); } } void output() { ans.clear(); for(int i=1;i<=2*n+2;i++) flg[i]=0; for(int i=1;i<=n;i++) { if (flg[i]==1) continue; vector<int> tmp; tmp.clear(); ans.push_back(tmp); dfs2(i,ans[ans.size()-1]); } printf("%d\n",ans.size()); for(int i=0;i<ans.size();i++) { printf("%d ",ans[i].size()); for(int j=0;j<ans[i].size();j++) printf("%d ",ans[i][j]); printf("\n"); } } void work() { int i; for(i=1;i<=n;i++) { if (!bfs()) break; findpath(); } if (i!=n+1) { printf("Impossible\n"); return ; } output(); } void build() { for(int i=1;i<=2*n+2;i++) for(int j=1;j<=2*n+2;j++) w[i][j]=0; for(int i=1;i<=n;i++) { w[1][i+2]=2; w[i+n+2][2]=2; } tot=2*n+2; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) { if (b[a[i]+a[j]]==1) continue; w[i+2][j+n+2]=1; w[j+2][i+n+2]=1; } for(int i=1;i<=2*n+2;i++) for(int j=1;j<=2*n+2;j++) w1[i][j]=w[i][j]; } int main() { dog(); while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(); work(); } return 0; }