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
先将总费用累加,跑最大流用总费用相减就是最大利润。。
附上本蒟蒻的代码:
#include<cstdio>
#include<iostream>
#include<cstring>
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 (head<tail)
{
head++;
j=q[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;
}