C:度度熊的礼物
- 时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
-
度度熊拥有一个自己的Baidu空间,度度熊时不时会给空间朋友赠送礼物,以增加度度熊与朋友之间的友谊值。度度熊在偶然的机会下得到了两种超级礼物,于是决定给每位朋友赠送一件超级礼物。不同类型的朋友在收到不同的礼物所能达到的开心值是不一样的。开心值衡量标准是这样的:每种超级礼物都拥有两个属性(A, B),每个朋友也有两种属性(X, Y),如果该朋友收到这个超级礼物,则这个朋友得到的开心值为A*X + B*Y。
由于拥有超级礼物的个数限制,度度熊很好奇如何分配这些超级礼物,才能使好友的开心值总和最大呢?
- 输入
- 第一行n表示度度熊的好友个数。 接下来n行每行两个整数表示度度熊好朋友的两种属性值Xi, Yi。 接下来2行,每行三个整数ki, Ai, Bi,表示度度熊拥有第i种超级礼物的个数以及两个属性值。 1 <= n <= 1000, 0 <= Xi, Yi, Ai, Bi <= 1000, 0 <= ki <= n, 保证k1+k2 >= n
- 输出
- 输出一行一个值表示好友开心值总和的最大值
- 样例输入
-
4 3 6 7 4 1 5 2 4 3 3 4 3 4 3
- 样例输出
-
118
View Code
#include <iostream> #include <stdio.h> #include <queue> #include <math.h> #include <string.h> using namespace std; #define V 5500 #define E 5007000 #define inf 0x3F3F3F3F int n,m; int vis[V]; int dist[V]; int pre[V]; struct Edge{ int u,v,c,cost,next; }edge[E]; int head[V],cnt; void init(){ cnt=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v,int c,int cost){ edge[cnt].u=u;edge[cnt].v=v;edge[cnt].cost=cost; edge[cnt].c=c;edge[cnt].next=head[u];head[u]=cnt++; edge[cnt].u=v;edge[cnt].v=u;edge[cnt].cost=-cost; edge[cnt].c=0;edge[cnt].next=head[v];head[v]=cnt++; } bool spfa(int begin,int end){ int u,v; queue<int> q; for(int i=0;i<=end+2;i++){ pre[i]=-1; vis[i]=0; dist[i]=inf; } vis[begin]=1; dist[begin]=0; q.push(begin); while(!q.empty()){ u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=edge[i].next){ if(edge[i].c>0){ v=edge[i].v; if(dist[v]>dist[u]+edge[i].cost){ dist[v]=dist[u]+edge[i].cost; pre[v]=i; if(!vis[v]){ vis[v]=true; q.push(v); } } } } } return dist[end]!=inf; } int MCMF(int begin,int end){ int ans=0,flow; int flow_sum=0; while(spfa(begin,end)){ flow=inf; for(int i=pre[end];i!=-1;i=pre[edge[i].u]) if(edge[i].c<flow) flow=edge[i].c; for(int i=pre[end];i!=-1;i=pre[edge[i].u]){ edge[i].c-=flow; edge[i^1].c+=flow; } ans+=dist[end]; flow_sum+=flow; } return ans; } int main() { //freopen("in.txt","r",stdin); int fri[1050][2],gift[2][3]; while(scanf("%d",&n)!=EOF){ for(int i=1;i<=n;i++){ scanf("%d%d",&fri[i][0],&fri[i][1]); } for(int i=0;i<2;i++){ scanf("%d%d%d",&gift[i][0],&gift[i][1],&gift[i][2]); } init(); for(int i=1;i<=n;i++){ addedge(0,i,1,0); } for(int i=n+1;i<=n+gift[0][0]+gift[1][0];i++){ addedge(i,n+gift[0][0]+gift[1][0]+1,1,0); } for(int i=1;i<=n;i++){ for(int j=n+1;j<=n+gift[0][0];j++){ addedge(i,j,1,-(fri[i][0]*gift[0][1]+fri[i][1]*gift[0][2])); } for(int j=n+gift[0][0]+1;j<=n+gift[0][0]+gift[0][1];j++){ addedge(i,j,1,-(fri[i][0]*gift[1][1]+fri[i][1]*gift[1][2])); } } int res=MCMF(0,n+gift[0][0]+gift[1][0]+1); printf("%d\n",-res); } return 0; }