BZOJ1391order

1391: [Ceoi2008]order
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 1055 Solved: 313
Description
有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成。 现在给出这些参数,求最大利润
Input
第一行给出 N,M(1<=N<=1200,1<=M<=1200) 下面将有N块数据,每块数据第一行给出完成这个任务能赚到的钱(其在[1,5000])及有多少道工序 接下来若干行每行两个数,分别描述完成工序所需要的机器编号及租用它的费用(其在[1,20000]) 最后M行,每行给出购买机器的费用(其在[1,20000])
Output
最大利润
Sample Input
2 3
100 2
1 30
2 20
100 2
1 40
3 80
50
80
110
Sample Output
50
HINT
BZOJ1391order_第1张图片
先将总费用累加,跑最大流用总费用相减就是最大利润。。
附上本蒟蒻的代码:

#include
#include
#include
using namespace std;
int n,m,cnt=1,head,tail,dis[10001],q[10001],h[10001],ans=0,sum=0;
struct kx
{
    int to,next,v;
}edge[3000001];

int read()
{
    int x=0,f=1; char ch=getchar();
    while (ch<'0' || ch>'9')
      {
        if (ch=='-') f=-1;
        ch=getchar();
      }
    while (ch>='0' && ch<='9')
      x=x*10+ch-'0',ch=getchar();
    return x*f;
}

void add(int u,int v,int w)
{
    cnt++,edge[cnt].next=h[u],h[u]=cnt,edge[cnt].to=v,edge[cnt].v=w;
    cnt++,edge[cnt].next=h[v],h[v]=cnt,edge[cnt].to=u,edge[cnt].v=0;
}

bool bfs()
{
    int j,p;
    memset(dis,-1,sizeof(dis));
    q[0]=0;
    dis[0]=0;
    head=0;
    tail=1;
    while (headq[head];
        p=h[j];
        while (p)
          {
            if (dis[edge[p].to]<0 && edge[p].v>0)
              {
                  dis[edge[p].to]=dis[j]+1;
                  tail++;
                  q[tail]=edge[p].to;
              }
            p=edge[p].next;
          }
      }
    if (dis[n+m+1]>0)
      return true;
    else
      return false;
}

int dfs(int x,int f)
{
    int w,used=0,i=h[x];
    if (x==n+m+1)
      return f;
    while (i)
      {
        if (edge[i].v && dis[edge[i].to]==dis[x]+1)
          {
            w=f-used;
            w=dfs(edge[i].to,min(w,edge[i].v));
            edge[i].v-=w;
            edge[i^1].v+=w;
            used+=w;
            if (used==f)
              return f;
          }
        i=edge[i].next;
      }
    if (!used)
      dis[x]=-1;
    return used;
}


int main()
{
    int i,a,b,c,d,j;
    n=read(),m=read();
    for (i=1;i<=n;i++)
      {
        a=read(),b=read();
        add(0,i,a),ans+=a;
        for (j=1;j<=b;j++)
          {
            c=read(),d=read();
            add(i,n+c,d);
          }
      }
    for (i=1;i<=m;i++)
      a=read(),add(n+i,n+m+1,a);
    while (bfs())
      while (sum=dfs(0,0x7fffffff))
        ans-=sum;
    printf("%d",ans);
    return 0;
}

你可能感兴趣的:(最大流)