抄了个DINIC的模板,然后模拟一下。
#include <bits/stdc++.h> using namespace std; const int maxn=80005; const int inf=0x3f3f3f3f; typedef vector<int> vi; typedef vector<vi> vii; bool vis[maxn]; vector<int>odd,even; vii ans; void init(){ for(int i=2;i<maxn;i++)if(!vis[i]){ for(int j=i*2;j<maxn;j+=i)vis[j]=1; } } struct Edge{ int from,to,cap,flow; Edge(){} Edge(int from,int to,int cap,int flow):from(from),to(to),cap(cap),flow(flow){} }; struct Dinic{ int n,m,s,t; vector<Edge>edges; vector<int>g[205]; bool vis[205]; int d[205]; int cur[205]; void init(int n){ this->n=n; edges.clear(); for(int i=0;i<=n;i++)g[i].clear(); } void addedge(int from,int to,int cap){ edges.push_back(Edge(from,to,cap,0)); edges.push_back(Edge(to,from,0,0)); m=edges.size(); g[from].push_back(m-2); g[to].push_back(m-1); } bool bfs(){ memset(vis,0,sizeof vis); queue<int>q; q.push(s); d[s]=0; vis[s]=1; while(!q.empty()){ int x=q.front();q.pop(); for(int i=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); } } } return vis[t]; } int dfs(int x,int a){ if(x==t||a==0)return a; int flow=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){ e.flow+=f; edges[g[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0)break; } } return flow; } int maxflow(int s,int t){ this->s=s; this->t=t; int flow=0; while(bfs()){ memset(cur,0,sizeof cur); flow+=dfs(s,inf); } return flow; } }solve; int main() { // freopen("in","r",stdin); init(); int n,a[222]; while(scanf("%d",&n)>0){ solve.init(n+1); odd.clear();even.clear(); for(int i=1;i<=n;i++){ scanf("%d",a+i); if(a[i]%2)odd.push_back(i); else even.push_back(i); } if(odd.size()!=even.size()){ puts("Impossible"); continue; } for(int i=0;i<odd.size();i++)solve.addedge(0,odd[i],2); for(int i=0;i<even.size();i++)solve.addedge(even[i],n+1,2); for(int i=0;i<odd.size();i++) for(int j=0;j<even.size();j++)if(!vis[a[odd[i]]+a[even[j]]])solve.addedge(odd[i],even[j],1); int MAX=solve.maxflow(0,n+1); if(MAX!=n)puts("Impossible"); else{ ans.clear(); vi res; bool vis[222]; memset(vis,0,sizeof vis); for(int i=1;i<=n;i++){ if(vis[i])continue; res.clear(); vis[i]=1; int cnt=0; res.push_back(i); int c=(a[i]%2)?1:-1; for(int j=0;j<solve.g[i].size();j++){ Edge x=solve.edges[solve.g[i][j]]; if(x.flow==c){ res.push_back(x.to); vis[x.to]=1; if(++cnt==2)break; } } // cout<<res.size()<<endl; // for(int i=0;i<res.size();i++)printf("%d%c",res[i],i==res.size()-1?'\n':' '); int now=res[res.size()-1]; while(now){ c*=-1; int newnow=0; cnt=0; for(int j=0;j<solve.g[now].size();j++){ Edge x=solve.edges[solve.g[now][j]]; if(x.flow==c){ if(!vis[x.to]){ vis[x.to]=1; newnow=x.to; res.push_back(x.to); } if(++cnt==2)break; } } now=newnow; } ans.push_back(res); } cout<<ans.size()<<endl; for(int i=0;i<ans.size();i++){ vi x=ans[i]; cout<<x.size(); printf(" %d %d",x[1],x[0]); for(int j=2;j<x.size();j++)printf(" %d",x[j]); puts(""); } } } return 0; }