BZOJ1391: [Ceoi2008]order
1391: [Ceoi2008]order
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 534 Solved: 170
[Submit][Status]
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
100 2
1 30
2 20
100 2
1 40
3 80
50
80
110
Sample Output
50
HINT
Source
题解:
一直在纠结怎么解决当租用机器的钱超过购买机器的钱的时候选择购买,想了想最大权闭合子图,发现不对,费用流,还是无果。
结果一看题解,瞬间石化了。
源点向每个任务连流量为任务权值的边、
任务向机器连租金的边、、
机器向汇点连售价的边、、
答案为、任务利润和-最大流、、
这个最大流实际上跑的是最小费用,为什么?还待思考。。。
。。。。。。。。。。。。。。
我的脑洞好大。。。。。。。。
连续提交7次都是WA,实在受不了了叫了hzwer大大的代码。。。
代码:
View Code
这个最大流实际上跑的是最小费用,为什么?还待思考。。。
。。。。。。。。。。。。。。
我的脑洞好大。。。。。。。。
连续提交7次都是WA,实在受不了了叫了hzwer大大的代码。。。
代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define inf 0x7fffffff 5 using namespace std; 6 int T,n,m,cnt=1,ans,cur[2501],q[2505],head[2505],h[2505]; 7 struct data{int to,next,v;}e[3000001]; 8 void ins(int u,int v,int w) 9 {cnt++;e[cnt].to=v;e[cnt].v=w;e[cnt].next=head[u];head[u]=cnt;} 10 void insert(int u,int v,int w) 11 {ins(u,v,w);ins(v,u,0);} 12 bool bfs() 13 { 14 int t=0,w=1,i,now; 15 for(int i=1;i<=T;i++)h[i]=-1; 16 q[0]=h[0]=0; 17 while(t!=w) 18 { 19 now=q[t];t++;if(t==2501)t=0; 20 for(i=head[now];i;i=e[i].next) 21 { 22 if(e[i].v&&h[e[i].to]<0) 23 {h[e[i].to]=h[now]+1;q[w++]=e[i].to;if(w==2501)w=0;} 24 } 25 } 26 if(h[T]==-1)return 0;return 1; 27 } 28 int dfs(int x,int f) 29 { 30 if(x==T)return f; 31 int w,used=0; 32 for(int i=cur[x];i;i=e[i].next) 33 { 34 if(e[i].v&&h[e[i].to]==h[x]+1) 35 { 36 w=f-used; 37 w=dfs(e[i].to,min(w,e[i].v)); 38 e[i].v-=w;if(e[i].v>0)cur[x]=i;e[i^1].v+=w; 39 used+=w;if(used==f)return f; 40 } 41 } 42 if(!used)h[x]=-1; 43 return used; 44 } 45 void dinic(){while(bfs()){for(int i=0;i<=T;i++)cur[i]=head[i];ans-=dfs(0,inf);}} 46 int main() 47 { 48 scanf("%d%d",&n,&m); 49 T=n+m+1; 50 int a,b,c,d; 51 for(int i=1;i<=n;i++) 52 { 53 scanf("%d%d",&a,&b); 54 insert(0,i,a);ans+=a; 55 for(int j=1;j<=b;j++) 56 { 57 scanf("%d%d",&c,&d); 58 insert(i,n+c,d); 59 } 60 } 61 for(int i=1;i<=m;i++) 62 { 63 scanf("%d",&a); 64 insert(n+i,T,a); 65 } 66 dinic(); 67 printf("%d",ans); 68 return 0; 69 }