codeforces290E

来源:互联网 发布:数据库中的decode 编辑:程序博客网 时间:2024/06/04 19:14

奇偶建图加输出路径

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <ctime>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;#define INF 0x3f3f3f3f#define inf -0x3f3f3f3f#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define mem0(a) memset(a,0,sizeof(a))#define mem1(a) memset(a,-1,sizeof(a))#define mem(a, b) memset(a, b, sizeof(a))typedef long long ll;int prime[20101];const int maxn=2001;int a[maxn];int Vis[maxn];struct node{    int x;    int id;}odd[maxn],even[maxn];vector<int>ans[maxn];struct Edge{    int from,to,cap,flow;    Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}};struct Dinic{    int n,m,s,t;                        //结点数,边数(包括反相弧),源点编号和汇点编号    vector<Edge>edges;                  //边表,edges[e]和edges[e^1]互为反相弧    vector<int>G[maxn];                 //邻接表,G[i][j]表示结点i的第j条边在e数组中的序号    bool vis[maxn];                     //BFS使用    int d[maxn];                        //从起点到i的距离    int cur[maxn];                      //当前弧下标    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);    }    void init(int n){        this->n=n;        for(int i=0;i<=n;i++)            G[i].clear();        edges.clear();    }    bool BFS(){        mem0(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()){            mem0(cur);            flow+=DFS(s,INF);        }        return flow;    }    void dfs1(int u,int top){        Vis[u]=1;        ans[top].push_back(u);        //printf("%d\n",G[u].size());        for(int i=0;i<G[u].size();i++){            Edge& e=edges[G[u][i]];            if(Vis[e.to]||e.to==0||e.to==n+1)                continue;            if(a[u]&1){                if(e.cap-e.flow==0){                    dfs1(e.to,top);                }            }            else{                if(e.cap-e.flow!=0){                    dfs1(e.to,top);                }            }        }    }};Dinic solve;int main(){    int n;    mem0(prime);    for(int i=2;i<=20001;i++){        if(!prime[i])        for(int j=i*i;j<=20001;j+=i){            prime[j]=1;        }    }    /*for(int i=2;i<=100;i++){        if(prime[i]==0)            cout<<i<<endl;    }*/    while(scanf("%d",&n)!=EOF){        solve.init(n);        for(int i=0;i<n;i++)            ans[i].clear();        int cnt1=0,cnt2=0;        for(int i=1;i<=n;i++){            scanf("%d",&a[i]);            if(a[i]%2==0){                even[cnt1].x=a[i];                even[cnt1++].id=i;                solve.AddEdge(i,n+1,2);            }            else{                odd[cnt2].x=a[i];                odd[cnt2++].id=i;                solve.AddEdge(0,i,2);            }        }        if(n%2==1){            printf("Impossible\n");            continue;        }        for(int i=0;i<cnt2;i++)            for(int j=0;j<cnt1;j++){                if(prime[odd[i].x+even[j].x]==0){                    solve.AddEdge(odd[i].id,even[j].id,1);                }            }        int flow=solve.Maxflow(0,n+1);        if(flow==n){            mem0(Vis);            int top=0;            for(int i=1;i<=n;i++){                if(Vis[i]==0){                    solve.dfs1(i,top++);                }            }            printf("%d\n",top);            for(int i=0;i<top;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;}
0 0
原创粉丝点击