Codeforces Round #290 (Div. 2) E. 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.
题意:给你n只狐狸,每只狐狸的年龄,你可以任意选择狐狸组成一张桌子,使得满足条件,并且全部坐上桌子;
条件:1、一张桌子最少最三只狐狸。二、相邻的两只狐狸年龄相加为素数,最后一只与第一只相邻。3都要坐上桌子。
思路:因为两两相加为素数,两个奇数不可能相加为素数(题目中每个数都大于2),所以相邻为一奇一偶,并且奇数个数等于偶数个数;
这样就可以把奇数与偶数分开,建立二分图,每个点需要匹配两个点,使得条件满足;
源点与奇数建流,并且流量为2,同理,偶数与汇点建流;最大流等于n满足答案的条件。
最后dfs暴力找答案的环;
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<set> #include<map> #include<queue> #include<stack> #include<vector> using namespace std; typedef long long ll; typedef pair<int,int> P; #define PI acos(-1.0) const int maxn=1e5+100,maxm=1e5+100,inf=0x3f3f3f3f,mod=1e9+7,N=1e5+10; const ll INF=1e18+7; vector<vector<int> >Ans; vector<int>out; int flag[N]; struct Dinic { struct edge { int from,to,cap,flow; }; vector<edge>es; vector<int>G[maxn]; bool vis[maxn]; int dist[maxn]; int iter[maxn]; void init(int n) { for(int i=0; i<=n+10; i++) G[i].clear(); es.clear(); } void addedge(int from,int to,int cap) { es.push_back((edge) { from,to,cap,0 }); es.push_back((edge) { to,from,0,0 }); int x=es.size(); G[from].push_back(x-2); G[to].push_back(x-1); } bool BFS(int s,int t) { memset(vis,0,sizeof(vis)); queue <int> Q; vis[s]=1; dist[s]=0; Q.push(s); while(!Q.empty()) { int u=Q.front(); Q.pop(); for (int i=0; i<G[u].size(); i++) { edge &e=es[G[u][i]]; if (!vis[e.to]&&e.cap>e.flow) { vis[e.to]=1; dist[e.to]=dist[u]+1; Q.push(e.to); } } } return vis[t]; } int DFS(int u,int t,int f) { if(u==t||f==0) return f; int flow=0,d; for(int &i=iter[u]; i<G[u].size(); i++) { edge &e=es[G[u][i]]; if(dist[u]+1==dist[e.to]&&(d=DFS(e.to,t,min(f,e.cap-e.flow)))>0) { e.flow+=d; es[G[u][i]^1].flow-=d; flow+=d; f-=d; if (f==0) break; } } return flow; } int Maxflow(int s,int t) { int flow=0; while(BFS(s,t)) { memset(iter,0,sizeof(iter)); int d=0; while(d=DFS(s,t,inf)) flow+=d; } return flow; } void solve(int u) { out.push_back(u); for(int i=0;i<G[u].size();i++) { edge x=es[G[u][i]]; //cout<<u<<" "<<x.from<<" "<<x.to<<" "<<x.flow<<endl; if(flag[x.to]||x.flow==0)continue; flag[x.to]=1; solve(x.to); } } } Din; int a[N]; int vis[N]; void prime() { for(int i=2; i<=20000; i++) { if(vis[i])continue; for(int j=i+i; j<=20000; j+=i) vis[j]=1; } } int main() { prime(); int n; scanf("%d",&n); Din.init(n); for(int i=1; i<=n; i++) { scanf("%d",&a[i]); if(a[i]%2)Din.addedge(0,i,2); else Din.addedge(i,n+1,2); } for(int i=1; i<=n; i++) { for(int j=i+1; j<=n; j++) { if(a[i]%2&&a[j]%2==0) { if(!vis[a[i]+a[j]]) Din.addedge(i,j,1); } else if(a[i]%2==0&&a[j]%2) { if(!vis[a[i]+a[j]]) Din.addedge(j,i,1); } } } int ans=Din.Maxflow(0,n+1); if(ans==n){ flag[0]=1; flag[n+1]=1; for(int i=1;i<=n;i++) { if(!flag[i]) { out.clear(); flag[i]=1; Din.solve(i); Ans.push_back(out); } } 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"); } } else printf("Impossible\n"); return 0; }