LOADING

加载过慢请开启缓存,浏览器默认开启

daily 1

2023/5/19 daily

CF 730I

MCMF的裸题,注意求最大值就建立负的边权就好了

struct MCMF{
  struct edge{
    int u,v;
    ll cap,cost;
  };
  const ll INF=1e18;
  int s,t;//source and des
  ll mincostflow;//the MCMF answer
  ll maxflow;//the maxflow
  vector<edge>Edge;//all edges
  vector<vector<int>>E;//the graph
  vector<ll>dis;//distance between source and i
  vector<int>vis;//whether this point in the loose queue or not
  MCMF(int n,int source,int sink){
    E.resize(n+1);
    dis.resize(n+1);
    vis.resize(n+1);
    s=source;
    t=sink;
    mincostflow=0;
    maxflow=0;
  }
  void add_edge(int u,int v,int cap,int cost){
    E[u].push_back(Edge.size());
    Edge.push_back({u,v,cap,cost});
    E[v].push_back(Edge.size());
    Edge.push_back({v,u,0,-cost});
  }
  bool spfa(){
    fill(dis.begin(),dis.end(),INF);
    queue<int>q;
    q.push(s);
    vis[s]=1;
    dis[s]=0;
    while(!q.empty()){
      auto tmp=q.front();
      q.pop();
      vis[tmp]=0;
      for(int id:E[tmp]){
        auto e=Edge[id];
        int to=e.v;
        if(e.cap>0&&dis[to]>dis[tmp]+e.cost){
          dis[to]=dis[tmp]+e.cost;
          if(!vis[to]){
            q.push(to);
            vis[to]=1;
          }
        }
      }
    }
    return dis[t]!=INF;
  } 
  ll dfs(int u,ll flow){
    if(u==t)
      return flow;
    vis[u]=1;
    ll ans=0;
    for(int i=E[u].size()-1;i>=0;--i){
      int id=E[u][i];
      auto e=Edge[id];
      int v=e.v;
      if(e.cap&&!vis[v]&&dis[v]==dis[u]+e.cost){
        ll cur_flow=dfs(v,min(flow-ans,e.cap));//the flow of the remaining graph
        if(cur_flow){
          if(ans+cur_flow>flow)
            break;
          mincostflow+=cur_flow*e.cost;
          ans+=cur_flow;
          Edge[id^1].cap+=cur_flow;
          Edge[id].cap-=cur_flow;
        }
      }
    }
    vis[u]=0;
    return ans;
  }
  ll get_mcmf(){
    maxflow=0;
    while(spfa()){
      int cur_flow;
      while((cur_flow=dfs(s,INF)))maxflow+=cur_flow;
    }
    return mincostflow;
  }
};
void solve(){
  int n,p,s,q,t;
  cin>>n>>p>>q;
  int source=n+1,sink=n+2,T1=n+3,T2=n+4;
  vector<int>a(n+1),b(n+1);
  for(int i=1;i<=n;++i)cin>>a[i];
  for(int i=1;i<=n;++i)cin>>b[i];
  MCMF mf(n+5,source,sink);
  for(int i=1;i<=n;++i){
    mf.add_edge(source,i,1,0);
    mf.add_edge(i,T1,1,-a[i]);
    mf.add_edge(i,T2,1,-b[i]);
  } 
  mf.add_edge(T1,sink,p,0);
  mf.add_edge(T2,sink,q,0);
  mf.get_mcmf();
  ll ans=mf.mincostflow;
  vector<int>ansa,ansb;
  for(int i=1;i<=n;++i){
    for(int id:mf.E[i]){
        auto e=mf.Edge[id];
        if(e.cap==0){
            if(e.v==T1){
                ansa.push_back(i);
            }else if(e.v==T2){
                ansb.push_back(i);
            }
        }
    }
  }
  cout<<-ans<<'\n';
  for(auto a:ansa){
    cout<<a<<' ';
  }
  cout<<'\n';
  for(auto b:ansb){
    cout<<b<<' ';
  }
  cout<<'\n';
  return;
}