Codeforces Fox And Dinner(最大流)

抄了个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?'
':' ');
                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;
}

  

原文地址:https://www.cnblogs.com/wshh/p/4282258.html