• 百度之星初赛第二场C题费用流求最大权匹配


    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;
    }
  • 相关阅读:
    HDU
    01字典树模板
    扩展欧几里得和乘法逆元
    HDOJ-1156 Brownie Points II 线段树/树状数组(模板)
    CF-825E Minimal Labels 反向拓扑排序
    CF-831D Office Keys 思维题
    RMQ 解决区间查询问题
    hdu 5073 有坑+方差贪心
    hdu 5074 相邻数和最大dp
    hdu 5078 水题
  • 原文地址:https://www.cnblogs.com/markliu/p/2532637.html
Copyright © 2020-2023  润新知