题目链接:http://codeforces.com/problemset/problem/321/B

题意:两个人,分别有n、m张牌。每张牌有两个属性类型和能力,类型为攻击或者防守。B的m张牌的属性均为攻击。模拟以下过程:

(1)B所有的牌都使用过,结束;否则,B此时想要结束则结束,不想结束转(2);

(2)B从自己未使用过的牌中选出一张,设其能力值为X,转(3);

(3)A所有牌都使用过,A受到的伤害值为X,转(1);否则转(4);

(4)B从A未使用过的牌中选出一张,设其能力值为Y,若这张牌类型为攻击,能当X>=Y时,此轮进行,A受到伤害值X-Y;若类型为防守,则当X>Y时此轮进行,A不受到伤害。此轮一旦进行,结束后两个人使用的牌均标记使用过。转(1)。

帮助B设计一个方案使得A受到的伤害值最大?

思路:使用费用流,三个问题:

(1)A在使用完所有牌后若B还有剩余则那些剩余牌的伤害值才能加入答案;也就是若A还有牌要先保证使用完A的牌

(2)B在任意时刻可以决定结束;

(3)此题是求最大值,而费用流是求最小费用;

我们这样建图,A的n张牌拆开,编号i和i+n,B的m张牌编号n+n+1到n+n+m,增加原点S=n+n+m+1,t=n+n+m+2。

(1)(i,i+n,1,-2*INF),(i+n,T,1,0),费用-INF*2,保证一定在答案中;(1<=i<=n)

(2)(0,n+n+i,1,0);  (1<=i<=m)

(3)(n+n+i,j,1,INF-(Xi-Yj))(攻击型),(n+n+i,j,1,INF)(防守型),最大改最小,符合最小费用,1<=i<=m,1<=j<=n

(4)(n+n+i,T,1,INF),A用完之后剩下的B直接加入答案;

(5)(S,0,x,0)这里的x是枚举的,枚举1到m,代表B在任意时刻可以决定是否结束。

计算最小费用后转换为实际答案就好。

struct node
{
    int u,v,flow,next;
    i64 cost;
};

node edges[N];
int head[N],e;

void add(int u,int v,int flow,i64 cost)
{
    edges[e].u=u;
    edges[e].v=v;
    edges[e].flow=flow;
    edges[e].cost=cost;
    edges[e].next=head[u];
    head[u]=e++;
}

void Add(int u,int v,int flow,i64 cost)
{
    add(u,v,flow,cost);
    add(v,u,0,-cost);
}

int pre[N],F[N],visit[N],s,t;
i64 C[N];

int SPFA(int s,int t)
{
    int i;
    for(i=0;i<=t;i++) C[i]=inf*1000,F[i]=0,visit[i]=0;
    queue<int> Q;
    Q.push(s); C[s]=0; F[s]=INF;
    int u,v,f;
    i64 c;
    while(!Q.empty())
    {
        u=Q.front();
        Q.pop();

        visit[u]=0;
        for(i=head[u];i!=-1;i=edges[i].next)
        {
            v=edges[i].v;
            f=edges[i].flow;
            c=edges[i].cost;
            if(f>0&&C[v]>C[u]+c)
            {
                C[v]=C[u]+c;
                F[v]=min(F[u],f);
                pre[v]=i;
                if(!visit[v]) Q.push(v),visit[v]=1;
            }
        }
    }
    return F[t];
}

i64 MCMF(int s,int t)
{
    i64 ans=0;
    int i,temp,x;
    while(temp=SPFA(s,t))
    {
        for(i=t;i!=s;i=edges[pre[i]].u)
        {
            x=pre[i];
            ans+=temp*edges[x].cost;
            edges[x].flow-=temp;
            edges[x^1].flow+=temp;
        }
    }
    return ans;
}

string S[105];
int a[105],b[105],n,m;

i64 cal(int x)
{
    int i,j;
    s=n+n+m+1; t=n+n+m+2; clr(head,-1); e=0;
    FOR1(i,n) Add(i,n+i,1,-2*inf);
    FOR1(i,n) Add(n+i,t,1,0);
    FOR1(i,m) Add(0,n+n+i,1,0);
    Add(s,0,x,0);
    FOR1(i,m)
    {
        FOR1(j,n)
        {
            if(S[j]=="ATK")
            {
                if(b[i]>=a[j]) Add(n+n+i,j,1,inf-(b[i]-a[j]));
            }
            else
            {
                if(b[i]>a[j]) Add(n+n+i,j,1,inf);
            }
        }
    }
    FOR1(i,m) Add(n+n+i,t,1,inf-b[i]);
    i64 ans=MCMF(s,t);
    ans=ans+2*inf*min(x,n);
    ans=x*inf-ans;
    return ans;
}

int main()
{
    RD(n,m);
    int i;
    FOR1(i,n) RD(S[i]),RD(a[i]);
    FOR1(i,m) RD(b[i]);
    i64 ans=0;
    for(i=1;i<=m;i++)
    {
        ans=max(ans,cal(i));
    }
    PR(ans);
    return 0;
}

CF 321B Ciel and Duel(费用流)的更多相关文章

  1. CF:322D - Ciel and Duel 贪心 或者 DP 我用的贪心 。。难道sort跟qsort是不一样的么?

    D. Ciel and Duel time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  2. CF 277E Binary Tree on Plane (拆点 + 费用流) (KM也可做)

    题目大意: 平面上有n个点,两两不同.现在给出二叉树的定义,要求树边一定是从上指向下,即从y坐标大的点指向小的点,并且每个结点至多有两个儿子.现在让你求给出的这些点是否能构成一棵二叉树,如果能,使二叉 ...

  3. 【CF280D】 k-Maximum Subsequence Sum ,线段树模拟费用流

    昨天考试被教育了一波.为了学习一下\(T3\)的科技,我就找到了这个远古时期的\(cf\)题(虽然最后\(T3\)还是不会写吧\(QAQ\)) 顾名思义,这个题目其实可以建成一个费用流的模型.我们用流 ...

  4. CSU 1948: 超级管理员(普通费用流&&zkw费用流)

    Description 长者对小明施加了膜法,使得小明每天起床就像马丁的早晨一样. 今天小明早上醒来发现自己成了一位仓管员.仓库可以被描述为一个n × m的网格,在每个网格上有几个箱子(可能没有).为 ...

  5. bzoj1834: [ZJOI2010]network 网络扩容 费用流

    bzoj1834 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求: 1.在不扩容的情况下,1到N的最大流: 2.将1到N的最大流增加K所需的最小扩容 ...

  6. BZOJ2673 [Wf2011]Chips Challenge 费用流 zkw费用流 网络流

    https://darkbzoj.cf/problem/2673 有一个芯片,芯片上有N*N(1≤N≤40)个插槽,可以在里面装零件. 有些插槽不能装零件,有些插槽必须装零件,剩下的插槽随意. 要求装 ...

  7. BZOJ2055 80人环游世界 网络流 费用流 有源汇有上下界的费用流

    https://darkbzoj.cf/problem/2055 https://blog.csdn.net/Clove_unique/article/details/54864211 ←对有上下界费 ...

  8. Codeforces 708D 上下界费用流

    给你一个网络流的图 图中可能会有流量不平衡和流量>容量的情况存在 每调整一单位的流量/容量 需要一个单位的花费 问最少需要多少花费使得原图调整为正确(可行)的网络流 设当前边信息为(u,v,f, ...

  9. hdu-5988 Coding Contest(费用流)

    题目链接: Coding Contest Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Ot ...

随机推荐

  1. oracle 的索引

    一.索引分类      按逻辑分: 单列索引(Single column):  单列索引是基于单列所创建的索引 复合(多列)索引(Concatenated ): 复合索引是基于两列或者多列所创建的索引 ...

  2. 夺命雷公狗---node.js---14之DNS

    node下如果想域名解析是需要通过apache或者ng的反向版定才可以实现的,但是他也给我们留下了哟套DNS操作方法: /** * Created by leigood on 2016/8/30. * ...

  3. RobotFramework 安装配置(二)

    前面已经写了一篇关于RF的安装配置了,那是在做自动化工具调研的时候搭建RF总结的,基于win32的系列软件安装的过程.经过1个月的调研,做成了demo,也大致学RF的使用和python的基础语法,暂时 ...

  4. PIC18F中断定时器

    //基于MCC18编译器,使用HI-PICC不可用 //-------------------------------------------- #include <p18F452.h> ...

  5. SSAS维度上有多个表的注意事项

    在Sql Server Analysis Service中维度上有多张表(大于一张表)时,一定要注意将第二张表开始用到维度属性中的KeyColumns下的NullProcessing要设置为Unkno ...

  6. tmpfs

    什么是tmpfs tmpfs是Linux/Unix系统上的一种基于内存的文件系统.tmpfs可以使用您的内存或swap分区来存储文件.由此可见,temfs主要存储暂存的文件. linux内核中的VM子 ...

  7. 使用git和github托管个人项目

    1.  安装 cygwin 和 cygwin 下的 git , 测试 git 命令可用;   参考: https://cygwin.com/install.html 2.  注册 github 账号: ...

  8. IT书籍的选择与阅读

    拍摄是一件艰苦而有趣的事情. 它需要眼睛和心灵完全融合投入, 需要耐心等待排除干扰, 需要敏捷捕捉稍纵即逝的瞬间. 但是, 非艰苦不成乐趣. 人生也应该选择一件有难度的事情来做. 做不成, 可以收获过 ...

  9. Java汉诺塔算法

    汉诺塔问题[又称河内塔]是印度的一个古老的传说. 据传开天辟地之神勃拉玛在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地把 ...

  10. TI CC2541的LED控制

    现在终于进入到蓝牙SPI的环节了, 下面还要研究I2C, 所以第一步, 先点灯, 就是GPIO控制吧. 参考一下LEd的初始化: void HalLedInit (void){#if (HAL_LED ...