Network flow.
The origin to even the even edge, the capacity is 2,
Odd to the meeting point with a capacity of 2,
An even to an odd number of edges with which it can be formed, with a capacity of 1
If an odd number of numbers is not equal to an even number of numbers, the output cannot
Output is not possible if the origin is not current to even-numbered edges
The rest of the situation has a solution: because a couple of points selected two odd points, a singular points by two even points selected, must be able to construct a ring.
#include <cstdio>#include<cstring>#include<string>#include<cmath>#include<vector>#include<queue>#include<algorithm>using namespacestd;Const intMAXN = -+Ten;Const intINF =0x7FFFFFFF;structedge{int from, to, cap, flow; Edge (intUintVintCintf): from(U), to (v), Cap (c), Flow (f) {}};vector<Edge>Edges;vector<int>G[MAXN];BOOLVIS[MAXN];intD[MAXN];intCUR[MAXN];intN, m, S, T;intNum[maxn];vector<int>G[maxn];vector<int>ANS[MAXN];BOOLF[MAXN];intBlock;voidinit () { for(inti =0; i < MAXN; i++) g[i].clear (); Edges.clear ();}voidAddedge (int from,intTo,intcap) {Edges.push_back (Edge ( from, to, Cap,0)); Edges.push_back (Edge to, from,0,0)); intW =edges.size (); g[ from].push_back (W-2); G[to].push_back (W-1);}BOOLBFS () {memset (Vis,0,sizeof(VIS)); Queue<int>p; Q.push (s); D[s]=0; Vis[s]=1; while(!Q.empty ()) { intx =Q.front (); Q.pop (); for(inti =0; I<g[x].size (); i++) {Edge e=Edges[g[x][i]]; if(!vis[e.to] && e.cap>e.flow) {vis[e.to]=1; D[e.to]= D[x] +1; Q.push (e.to); } } } returnvis[t];}intDasointXinta) { if(x = = T | | a = =0) returnA; intFlow =0, F; for(int&i = Cur[x]; I<g[x].size (); i++) {Edge e=Edges[g[x][i]]; if(d[x]+1= = d[e.to]&& (F=dfs (E.to,min (a,e.cap-e.flow)) >0) {Edges[g[x][i]].flow+=F; Edges[g[x][i]^1].flow-=F; Flow+=F; A-=F; if(a==0) Break; } } if(!flow) d[x] =-1; returnflow;}intDinic (intSintt) { intFlow =0; while(BFS ()) {memset (cur,0,sizeof(cur)); Flow+=DFS (S, INF); } returnflow;}BOOLPrimeintx) { for(intI=2; i*i<=x;i++) if(x%i==0)return 0; return 1;}voidFind (intNow ) {F[now]=1; Ans[block].push_back (now); for(intI=0; I<g[now].size (); i++) { if(F[g[now][i]])Continue; Find (G[now][i]); }}intMain () { while(~SCANF ("%d",&N)) { for(intI=1; i<=n;i++) scanf ("%d",&Num[i]); Init (); S=0; t=n+1;inte1=0, e2=0; intflag=0; for(intI=1; i<=n;i++) { if(num[i]%2==0) {e1++; Addedge (S,i,2); } Else{e2++; Addedge (I,t,2); } } if(E1!=E2) flag=1; Else { for(intI=1; i<=n;i++) for(intj=1; j<=n;j++) if(num[i]%2==0&&num[j]%2==1&&prime (num[i]+Num[j])) Addedge (I,j,1); intflow=dinic (s,t); if(flow!=2*E1) flag=1; } if(flag==1) printf ("impossible\n"); Else{block=0; Memset (F,0,sizeoff); for(intI=0; i<maxn;i++) {g[i].clear (); Ans[i].clear ();} for(intI=0; I<edges.size (); i=i+2) { if(edges[i].flow==1) { intU=edges[i]. from; intv=edges[i].to; G[u].push_back (v); G[v].push_back (U); } } for(intI=1; i<=n;i++) { if(F[i])Continue; Find (i); Block++; } printf ("%d\n", block); for(intI=0; i<block;i++) {printf ("%d", Ans[i].size ()); for(intj=0; J<ans[i].size (); j + +) printf ("%d", Ans[i][j]); printf ("\ n"); } } } return 0;}
Codeforces 510E Fox and Dinner