太空飞行计划问题(网络流24题)

题意

有m个实验,n个器材,每个实验做完会得到一些钱,每个实验需要一些器械才能完成,买器材会花钱,器材可以一起用,求最大利益。

n,m<=50

题解

直接写做法了,没做过就想不出来。

源点向实验连边,流量为实验所得的钱,器材想汇点连边,流量为器材花费,实验与相应的器材连边,流量inf。

先假设没花钱做了所有实验得到了所有钱ans(不要face)。

求一遍最小割即可,ans-最小割就是答案。

割掉实验的连边就是不做这个实验,割掉器材的连边就是买这个器材。

输出方案就输出与s连通的即可。(为啥我也不知道)

#include<bits/stdc++.h>
using namespace std;

const int maxn=105;
const int maxm=2705;
const int inf=1000005;
int n,m,s,t,ans;
int val[maxn];
bool flag,get[maxn];
int cnt=1,head[maxn];
struct edge{
  int x,y,next,val;
}e[maxm<<1];

void add(int x,int y,int val){
  e[++cnt]=(edge) {x,y,head[x],val};
  head[x]=cnt;
}

template<class T>inline void read(T &x){
  x=0;char ch=getchar();
  while(!isdigit(ch)) ch=getchar();
  while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
  flag|=(ch=='
');
}

int d[maxn];

bool bfs(){
  queue<int> q;
  memset(d,0,sizeof(d));
  q.push(s);d[s]=1;
  while(!q.empty()){
    int x=q.front();
    q.pop();
    for(int i=head[x];i;i=e[i].next){
      int y=e[i].y;
      if(e[i].val&&!d[y]){
        d[y]=d[x]+1;
        if(y==t) return true;
        q.push(y);
      }
    }
  }
  return false;
}

int dfs(int x,int flow){
  if(x==t) return flow;
  int rest=flow,k;
  for(int i=head[x];i;i=e[i].next){
    int y=e[i].y;
    if(e[i].val&&d[y]==d[x]+1){
      k=dfs(y,min(rest,e[i].val));
      if(!k) d[y]=0;
      e[i].val-=k;
      e[i^1].val+=k;
      rest-=k;
    }
  }
  return flow-rest;
}

int dinic(){
  int res=0;
  while(bfs()) res+=dfs(s,0x3f3f3f);
  return res;
}

int main(){
  read(m);read(n);
  s=0;t=n+m+1;
  for(int i=1;i<=m;i++){
    int x;read(x);
    ans+=x;
    add(s,i,x);
    add(i,s,0);
    flag=false;
    while(!flag){
      read(x);
      add(i,x+m,inf);
      add(x+m,i,0);
    }
  }
  for(int i=1;i<=n;i++){
    int x;read(x);
    add(i+m,t,x);
    add(t,i+m,0);
  }
  ans-=dinic();
  for(int i=1;i<=m;i++) if(d[i]) printf("%d ",i);
  putchar(10);
  for(int i=m+1;i<=n+m;i++) if(d[i]) printf("%d ",i-m);
  putchar(10);
  printf("%d",ans);
}
View Code
原文地址:https://www.cnblogs.com/sto324/p/11334074.html