hdu 3315 My Brute 费用流,费用最小且代价最小

很常见的想法了= =

#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
const int N=400;
const int MAXE=200000;
const int inf=1<<30;
int head[N],s,t,cnt,n,m,ans;
int d[N],pre[N];
bool vis[N];
int q[MAXE];
int V[N],H[N],P[N],A[N],B[N];
struct Edge
{
    int u,v,c,w,next;
}edge[MAXE];

void addedge(int u,int v,int w,int c)
{
    edge[cnt].u=u;
    edge[cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].c=c;
    edge[cnt].next=head[u];
    head[u]=cnt++;
    edge[cnt].v=u;
    edge[cnt].u=v;
    edge[cnt].w=-w;
    edge[cnt].c=0;
    edge[cnt].next=head[v];
    head[v]=cnt++;
}

int SPFA()
{
    int l,r;
    memset(pre,-1,sizeof(pre));
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=t;i++) d[i]=inf;
    d[s]=0;
    l=0;r=0;
    q[r++]=s;
    vis[s]=1;
    while(l<r)
    {
        int u=q[l++];
        vis[u]=0;
        for(int j=head[u];j!=-1;j=edge[j].next)
        {
            int v=edge[j].v;
            if(edge[j].c>0&&d[u]+edge[j].w<d[v])
            {
                d[v]=d[u]+edge[j].w;
                pre[v]=j;
                if(!vis[v])
                {
                    vis[v]=1;
                    q[r++]=v;
                }
            }
        }
    }
    if(d[t]==inf)
        return 0;
    return 1;
}

void MCMF()
{
    int flow=0;
    while(SPFA())
    {
        int u=t;
        int mini=inf;
        while(u!=s)
        {
            if(edge[pre[u]].c<mini)
                mini=edge[pre[u]].c;
                u=edge[pre[u]].u;
        }
        flow+=mini;
        u=t;
        ans+=d[t]*mini;
        while(u!=s)
        {
            edge[pre[u]].c-=mini;
            edge[pre[u]^1].c+=mini;
            u=edge[pre[u]].u;
        }
    }
}

int beat(int i,int j)
{
    int x,y;
    if(P[j]%A[i]==0)
        x=P[j]/A[i];
    else
        x=P[j]/A[i]+1;
    if(H[i]%B[j]==0)
        y=H[i]/B[j];
    else
        y=H[i]/B[j]+1;
    if(x<=y)
        return 1;
    else
        return 0;
}

int main()
{
    int i,j;
    while(1)
    {
        scanf("%d",&n);
        if(n==0) break;
        s=0;t=2*n+1;cnt=0;
        for(i=0;i<=t;i++)
            head[i]=-1;
        for(i=1;i<=n;i++)   scanf("%d",&V[i]);
        for(i=1;i<=n;i++)   scanf("%d",&H[i]);
        for(i=1;i<=n;i++)   scanf("%d",&P[i]);
        for(i=1;i<=n;i++)   scanf("%d",&A[i]);
        for(i=1;i<=n;i++)   scanf("%d",&B[i]);
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
            {

                if(beat(i,j))
                {
                    if(i==j) addedge(i,j+n,-(V[i]*100+1),1);
                    else addedge(i,j+n,-V[i]*100,1);
                }
                else
                {
                    if(i==j) addedge(i,j+n,V[i]*100-1,1);
                    else addedge(i,j+n,V[i]*100,1);
                }
            }

        for(i=1;i<=n;i++)
        {
            addedge(s,i,0,1);
            addedge(i+n,t,0,1);
        }
        ans=0;
        MCMF();
        if(ans>=0) printf("Oh, I lose my dear seaco!\n");
        else printf("%d %.3f%%\n",-ans/100,-1.0*100*(ans%100)/n);
    }
    return 0;
}

hdu 3315 My Brute 费用流,费用最小且代价最小

时间: 2024-10-17 12:46:26

hdu 3315 My Brute 费用流,费用最小且代价最小的相关文章

HDU 3315 My Brute(KM最大匹配)

HDU 3315 My Brute 题目链接 和HDU2835是一样的思路,利用把数字离散掉来多判断一个优先级 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int MAXNODE = 105; typedef int Type; const Type INF = 0x3f3f3f3f; str

HDU 3315 My Brute(费用流)

题目地址:HDU 3315 这个题的思路完全是自己想出来的,自我感觉挺巧妙的...(大牛勿喷...)对大胆建图又多了一份信心. 具体思路是构造一个二分图,Si连源点,Xi连汇点,流量都是1,费用0.然后当Si可以赢Xj的时候,就对这两人连一条边,费用值为-Vi*1000,如果i==j的话,费用值就再减1,因为题目要求尽量不改变原先的顺序,所以说应该尽量让序号相同的对打.而费用值减1的话,会优先考虑序号相同的,而且让费用扩大了1000倍,此时也不会改变主要的分数因素大小.同理,输的话,费用值为Vi

【BZOJ-2055】80人环游世界 上下界费用流 (无源无汇最小费用最大流)

2055: 80人环游世界 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 321  Solved: 201[Submit][Status][Discuss] Description 想必大家都看过成龙大哥的<80天环游世界>,里面的紧张刺激的打斗场面一定给你留下了深刻的印象.现在就有这么 一个80人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家. 因为他们主要分布在东方,所以他们只朝西方进军.设从东方到西方的每一个国家的编号依次为

[luoguP1251] 餐巾计划问题(费用流)

传送门 模型 网络优化问题,用最小费用最大流解决. 实现 把每天分为二分图两个集合中的顶点Xi,Yi,建立附加源S汇T. 1.从S向每个Xi连一条容量为ri,费用为0的有向边. 2.从每个Yi向T连一条容量为ri,费用为0的有向边. 3.从S向每个Yi连一条容量为无穷大,费用为p的有向边. 4.从每个Xi向Xi+1(i+1<=N)连一条容量为无穷大,费用为0的有向边. 5.从每个Xi向Yi+m(i+m<=N)连一条容量为无穷大,费用为f的有向边. 6.从每个Xi向Yi+n(i+n<=N)

【Codevs1237&amp;网络流24题餐巾计划】(费用流)

题意:一个餐厅在相继的 N 天里,每天需用的餐巾数不尽相同. 假设第 i 天需要 ri块餐巾(i=1,2,-,N).餐厅可以购买新的餐巾,每块餐巾的费用为 p 分: 或者把旧餐巾送到快洗部,洗一块需 m 天,其费用为 f 分: 或者送到慢洗部,洗一块需 n 天(n>m),其费用为 s<f 分.每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗. 但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量.试设计一个算法为餐厅合理地安排好 N 天

HDU 4862 Jump 最小k路径覆盖 费用流

gg... 题意: 给定n*m的矩阵 选<=k个起点 每个起点可以向右或向下跳任意步 花费是2点间的曼哈顿距离 若2个格子的数字一样 则赚取格子上的数字的价值 问:遍历整个图的最小花费 若不能遍历则输出-1 #include <stdio.h> #include <string.h> #include <iostream> #include <math.h> #include <queue> #include <set> #in

【进阶——最小费用最大流】hdu 1533 Going Home (费用流)Pacific Northwest 2004

题意: 给一个n*m的矩阵,其中由k个人和k个房子,给每个人匹配一个不同的房子,要求所有人走过的曼哈顿距离之和最短. 输入: 多组输入数据. 每组输入数据第一行是两个整型n, m,表示矩阵的长和宽. 接下来输入矩阵. 输出: 输出最短距离. 题解: 标准的最小费用最大流算法,或者用KM算法.由于这里是要学习费用流,所以使用前者. 最小费用最大流,顾名思义,就是在一个网络中,不止存在流量,每单位流量还存在一个费用.由于一个网络的最大流可能不止一种,所以,求出当前网络在流量最大的情况下的最小花费.

HDU 3316 My Brute(二维费用流)经典

My Brute Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 941    Accepted Submission(s): 372 Problem Description Seaco is a beautiful girl and likes play a game called "My Brute". Before Va

POJ 2135 Farm Tour &amp;&amp; HDU 2686 Matrix &amp;&amp; HDU 3376 Matrix Again 费用流求来回最短路

累了就要写题解,最近总是被虐到没脾气. 来回最短路问题貌似也可以用DP来搞,不过拿费用流还是很方便的. 可以转化成求满流为2 的最小花费.一般做法为拆点,对于 i 拆为2*i 和 2*i+1,然后连一条流量为1(花费根据题意来定) 的边来控制每个点只能通过一次. 额外添加source和sink来控制满流为2. 代码都雷同,以HDU3376为例. #include <algorithm> #include <iostream> #include <cstring> #in