CodeForces - 510E Fox And Dinner
因为元素大小>=2,所以能构成质数的两个数奇偶性一定不同。
于是构造一个二分图,每个点度数设为2,表示在环上有两个相邻点,跑个最大流,=n有解。。
求解的话直接在跑完网络流的图上dfs就行了。
别问我一开始为什么WA了,我把边从1开始标号于是反向边找错了mmp
#include<bits/stdc++.h> #define ll long long using namespace std; #define pb push_back const int N=305,inf=1e9; struct lines{ int to,flow,cap; }l[N*777]; vector<int> g[N],pt[N]; int cur[N],d[N],t=-1,S,T,p[N]; int num,zs[23333],a[N],n,fl,ans; bool v[N],V[23333]; inline void add(int from,int to,int cap){ l[++t]=(lines){to,0,cap},g[from].pb(t); l[++t]=(lines){from,0,0},g[to].pb(t); } inline bool BFS(){ memset(v,0,sizeof(v)),v[S]=1,d[S]=0; queue<int> q; q.push(S); int x; lines e; while(!q.empty()){ x=q.front(),q.pop(); for(int i=g[x].size()-1;i>=0;i--){ e=l[g[x][i]]; if(e.flow<e.cap&&!v[e.to]) v[e.to]=1,d[e.to]=d[x]+1,q.push(e.to); } } return v[T]; } int dfs(int x,int A){ if(x==T||!A) return A; int flow=0,f,sz=g[x].size(); for(int &i=cur[x];i<sz;i++){ lines &e=l[g[x][i]]; if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(e.cap-e.flow,A)))){ A-=f,flow+=f; e.flow+=f,l[g[x][i]^1].flow-=f; if(!A) break; } } return flow; } inline int max_flow(){ int an=0; while(BFS()){ memset(cur,0,sizeof(cur)); an+=dfs(S,inf); } return an; } inline void init(){ V[1]=1; for(int i=2;i<=20000;i++){ if(!V[i]) zs[++num]=i; for(int j=1,u;j<=num&&(u=zs[j]*i)<=20000;j++){ V[u]=1; if(!(i%zs[j])) break; } } } inline void build(){ S=0,T=n+1; 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) for(int j=1;j<=n;j++) if(!V[a[i]+a[j]]) add(i,j,1); } void B(int x){ lines e; pt[ans].pb(x),v[x]=1; for(int u:g[x]){ e=l[u]; if(e.flow&&e.to&&e.to<=n&&!v[e.to]) B(e.to); } } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",a+i); init(),build(); fl=max_flow(); if(fl<n){ puts("Impossible"); return 0;} /* for(int i=1;i<=t;i+=2) if(l[i].flow&&l[i].to!=S&&l[i^1].to!=S&&l[i].to!=T&&l[i^1].to!=T) printf("%d %d %d\n",l[i^1].to,l[i].to,l[i].flow); */ memset(v,0,sizeof(v)); for(int i=1;i<=n;i++) if(!v[i]) ans++,B(i); puts(""); printf("%d\n",ans); for(int i=1;i<=ans;i++){ printf("%d ",pt[i].size()); for(int u:pt[i]) printf("%d ",u); puts(""); } return 0; }
我爱学习,学习使我快乐