zoj 2071(Technology Trader) 最大权闭合图
2011-08-18 21:12
267 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2071
题意简述:商人有m个订单,每个订单能挣一定的钱,但是要完成每个订单需要购买不同的机器,题目问该商人最多能够挣多少钱?
分析:建图 源点到每个机器连边,权值为花费,订单到汇点连边权值为权值为收益,之后机器和订单有联系的连一条有向边从机器到订单,最后所有订单对应的收益之和减去最大流即为所求!
代码如下:
题意简述:商人有m个订单,每个订单能挣一定的钱,但是要完成每个订单需要购买不同的机器,题目问该商人最多能够挣多少钱?
分析:建图 源点到每个机器连边,权值为花费,订单到汇点连边权值为权值为收益,之后机器和订单有联系的连一条有向边从机器到订单,最后所有订单对应的收益之和减去最大流即为所求!
代码如下:
#include <iostream> #include <cstdio> #include<cstring> using namespace std; const int N = 400; const int E = 50000; const int inf=0x3f3f3f3f; int e,head ; int dep ,que ,cur ; struct node { int x,y; int nxt; int c; }edge[E]; void addedge(int u,int v,int c) { edge[e].x=u; edge[e].y=v; edge[e].nxt=head[u]; edge[e].c=c; head[u]=e++; edge[e].x=v; edge[e].y=u; edge[e].nxt=head[v]; edge[e].c=0; head[v]=e++; } int maxflow(int s,int t) { int i,j,k,front,rear,top,min,res=0; while(1) { memset(dep,-1,sizeof(dep)); front=0; rear=0; que[rear++]=s; dep[s]=0; while(front!=rear) { i=que[front++]; for(j=head[i];j!=-1;j=edge[j].nxt) if(edge[j].c&&dep[edge[j].y]==-1) { dep[edge[j].y]=dep[i]+1; que[rear++]=edge[j].y; } } if(dep[t]==-1) break; memcpy(cur,head,sizeof(head)); for(i=s,top=0;;) { if(i==t) { min=inf; for(k=0;k<top;k++) if(min>edge[que[k]].c) { min=edge[que[k]].c; front=k; } for(k=0;k<top;k++) { edge[que[k]].c-=min; edge[que[k]^1].c+=min; } res+=min; i=edge[que[top=front]].x; } for(j=cur[i];cur[i]!=-1;j=cur[i]=edge[cur[i]].nxt) if(dep[edge[j].y]==dep[i]+1&&edge[j].c) break; if(cur[i]!=-1) { que[top++]=cur[i]; i=edge[cur[i]].y; } else { if(top==0) break; dep[i]=-1; i=edge[que[--top]].x; } } } return res; } int main () { int t; int n, i,m,j,num,k; char name[260][35]; char s[35]; bool flag[110]; bool tag[260]; char order[110][35]; int c; scanf("%d",&t); int h = 0; while(t--) { h++; scanf("%d",&n); memset(head,-1,sizeof(head)); e = 0; for(i=1;i<=n;i++) { scanf("%s%d",name[i],&c); addedge(0,i,c); } scanf("%d",&m); int sum = 0; for(i=1;i<=m;i++) { scanf("%s%d",order[i],&c); sum += c; addedge(i+n,n+m+1,c); scanf("%d",&num); for(j=0;j<num;j++) { scanf("%s",s); for(k=1;k<=n;k++) if(strcmp(name[k],s)==0) break; if(k>n) continue; addedge(k,i+n,inf); } } int flow = maxflow(0,n+m+1); if(h>1) printf("\n"); printf("%d\n",sum-flow); memset(flag,0,sizeof(flag)); memset(tag,0,sizeof(tag)); num = 0; for(i=head[n+m+1];i!=-1;i=edge[i].nxt) { if(edge[i^1].c>0) { flag[edge[i].y-n]=1; num++; } } for(i=n+1;i<n+m+1;i++) if(flag[i-n]) for(j=head[i];j!=-1;j=edge[j].nxt) if(edge[j].y!=n+m+1) tag[edge[j].y]=1; int num1 = 0; for(i=1;i<=n;i++) if(tag[i]) num1++; printf("%d\n",num); for(i=1;i<=m;i++) if(flag[i]) printf("%s\n",order[i]); printf("%d\n",num1); for(i=1;i<=n;i++) if(tag[i]) puts(name[i]); // system("Pause"); } return 0; }
相关文章推荐
- 【ZOJ】2071 Technology Trader 最大权闭合子图
- zoj 2071 Technology Trader 最大权闭合子图
- ZOJ 2071 最大权闭合图
- ZOJ 3229 有上下界最大流
- ZOJ 3642 最大流
- zoj 2760 How Many Shortest Path 最大流
- ZOJ 1654 Place the Robots(放置机器人)------最大独立集
- hdu1081-最大子矩阵和(zoj-1074)
- POJ 1466 Girls and Boys (ZOJ 1137 )最大独立点集
- ZOJ 3229 Shoot the Bullet(有源汇的上下界最大流)
- ZOJ 1516 Uncle Tom's Inherited Land(二分匹配 最大匹配 匈牙利啊)
- zoj 3165 (最小割,最大点权独立集)
- [ACM_水题] ZOJ 3712 [Hard to Play 300 100 50 最大最小]
- ZOJ 3762 Pan's Labyrinth (点集中的最大点-线距&技巧性枚举)
- zoj 2676 Network Wars(01分数规划+最大流)
- zoj 3362 Beer Problem 【最大费用最大流 需要判断最长路值是否为负】
- 带花树(一般图最大匹配)详解 ZOJ 3316
- zoj 1492 最大团顶点数量
- zoj 1654 Place the Rebots 最大独立集转换成二分图最大独立边(最大匹配)
- zoj 1516 Uncle Tom's Inherited Land 最大独立边集合(最大匹配)