网络流(费用流)CodeForces 321B:Ciel and Duel

Fox Ciel is playing a card game with her friend Jiro.

Jiro has n cards, each one has two attributes: position (Attack or Defense) and strength. Fox Ciel has m cards, each one has these two attributes too. It‘s known that position of all Ciel‘s cards is Attack.

Now is Ciel‘s battle phase, Ciel can do the following operation many times:

  1. Choose one of her cards X. This card mustn‘t be chosen before.
  2. If Jiro has no alive cards at that moment, he gets the damage equal to (X‘s strength). Otherwise, Ciel needs to choose one Jiro‘s alive card Y, then:
    • If Y‘s position is Attack, then (X‘s strength)  ≥  (Y‘s strength) must hold. After this attack, card Y dies, and Jiro gets the damage equal to (X‘s strength) - (Y‘s strength).
    • If Y‘s position is Defense, then (X‘s strength)  >  (Y‘s strength) must hold. After this attack, card Y dies, but Jiro gets no damage.

Ciel can end her battle phase at any moment (so, she can use not all her cards). Help the Fox to calculate the maximal sum of damage Jiro can get.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 100) — the number of cards Jiro and Ciel have.

Each of the next n lines contains a string position and an integer strength (0 ≤ strength ≤ 8000) — the position and strength of Jiro‘s current card. Position is the string "ATK" for attack, and the string "DEF" for defense.

Each of the next m lines contains an integer strength (0 ≤ strength ≤ 8000) — the strength of Ciel‘s current card.

Output

Output an integer: the maximal damage Jiro can get.

Sample Input

Input

2 3ATK 2000DEF 1700250025002500

Output

3000

Input

3 4ATK 10ATK 100ATK 10001111011001

Output

992

Input

2 4DEF 0ATK 00011

Output

1

Hint

In the first test case, Ciel has 3 cards with same strength. The best strategy is as follows. First she uses one of these 3 cards to attack "ATK 2000" card first, this attack destroys that card and Jiro gets 2500 - 2000 = 500 damage. Then she uses the second card to destroy the "DEF 1700" card. Jiro doesn‘t get damage that time. Now Jiro has no cards so she can use the third card to attack and Jiro gets 2500 damage. So the answer is 500 + 2500 = 3000.

In the second test case, she should use the "1001" card to attack the "ATK 100" card, then use the "101" card to attack the "ATK 10" card. Now Ciel still has cards but she can choose to end her battle phase. The total damage equals (1001 - 100) + (101 - 10) = 992.

In the third test case note that she can destroy the "ATK 0" card by a card with strength equal to 0, but she can‘t destroy a "DEF 0" card with that card.

  这道题提示我们可以用INF强化优先级,之后减回来就好。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int N=1010,M=40010,INF=10000000;
 6 int n,m,cnt,fir[N],nxt[M],to[M],cap[M],val[M];
 7 int vis[N],dis[N],path[N],q[N],front,back;
 8 void addedge(int a,int b,int c,int v){
 9     nxt[++cnt]=fir[a];to[fir[a]=cnt]=b;cap[cnt]=c;val[cnt]=v;
10     nxt[++cnt]=fir[b];to[fir[b]=cnt]=a;cap[cnt]=0;val[cnt]=-v;
11     //printf("%d %d %d %d\n",a,b,c,v);
12 }
13
14 int BFS(int S,int T){
15     for(int i=S+1;i<=T;i++)dis[i]=10*INF;
16     q[front=back=1]=S;vis[S]=true;
17     while(front<=back){
18         int x=q[front++];vis[x]=false;
19         for(int i=fir[x];i;i=nxt[i])
20             if(cap[i]&&dis[to[i]]>dis[x]+val[i]){
21                 dis[to[i]]=dis[x]+val[i];
22                 if(!vis[to[i]])q[++back]=to[i];
23                 vis[to[i]]=true;path[to[i]]=i;
24             }
25     }
26     return dis[T];
27 }
28
29 void Aug(int S,int T){
30     int p=T;
31     while(p!=S){
32         cap[path[p]]-=1;
33         cap[path[p]^1]+=1;
34         p=to[path[p]^1];
35     }
36 }
37
38 int McMf(int S,int T){
39     int ret=0,d,tmp=0;
40     for(int i=1;i<=n;i++){
41         d=BFS(S,T);
42         if(d>=INF)return -ret;
43         tmp+=d;ret=min(ret,tmp);Aug(S,T);
44     }
45     for(int i=n+1;i<=m;i++){
46         d=BFS(S,T);
47         if(d==10*INF)return -ret;
48         tmp+=d-2*INF;ret=min(ret,tmp);Aug(S,T);
49     }
50     return -ret;
51 }
52
53 int A[N],D[N],B[N],ca,cd,S,T,x;
54 void Init(){
55     memset(dis,0,sizeof(dis));
56     memset(fir,0,sizeof(fir));
57     front=back=cnt=1;
58 }
59 char op[5];
60 int main(){
61     Init();
62     scanf("%d%d",&n,&m);
63     S=0;T=n+m+1;
64     for(int i=1;i<=n;i++){
65         scanf("%s%d",op,&x);
66         if(op[0]==‘A‘)A[++ca]=x;
67         if(op[0]==‘D‘)D[++cd]=x;
68     }
69     for(int i=1;i<=n;i++)
70         addedge(i+m,T,1,0);
71     for(int i=1;i<=m;i++){
72         scanf("%d",&B[i]);
73         addedge(S,i,1,0);
74         addedge(i,T,1,2*INF-B[i]);
75         for(int j=1;j<=ca;j++)
76             if(A[j]<=B[i])addedge(i,m+j,1,-B[i]+A[j]);
77         for(int j=1;j<=cd;j++)
78             if(D[j]<B[i])addedge(i,m+j+ca,1,0);
79     }
80     printf("%d\n",McMf(S,T));
81     return 0;
82 }    
时间: 2024-10-09 11:02:42

网络流(费用流)CodeForces 321B:Ciel and Duel的相关文章

Codeforces 321B Ciel and Duel

题意:对方有N张卡牌,每一张卡牌要么是攻击模式要么是防守模式,你有M张卡牌,都是攻击模式 ,每张卡牌都有一个值,你可以进行一下的任意操 1)如果对方牌都被你消灭了,那么你任选一张没有选过的牌是对方遭受牌值的攻击. 2)可以选择一张没有选过值为X的牌,攻击对方一张攻击模式值为Y 的牌  对对方造成(X-Y)的伤害并把牌消灭 X必须 大于等于Y 3)可以选择一张没有选过值为X的牌,攻击对方一张防守模式值为Y 的牌  对对方不造成伤害,把对方牌消灭. X必须大于Y 解题思路:暴力 + DP? 解题代码

Codeforces 321B Ciel and Duel KM

题目链接 题意: 类似于游戏王的卡牌游戏,每个随从都有嘲讽... 输入n m 下面n行给出对手的随从当前状态和强壮值. 下面m行给出自己的随从的强壮值. 表示自己有m个随从,对手有n个随从.每个随从有一个强壮值. 现在是自己进攻的回合,自己的每个随从可以攻击一次(也可以不攻击) 若对手的随从都死光了,那么可以直接攻击玩家,造成与强壮值相等的伤害. 否则就要先攻击对手的随从. 对手的随从有防御状态(Defense) 和 攻击状态(Attack),每个随从也有一个强壮值. 1.若攻击对手的攻击状态随

POJ训练计划3422_Kaka&#39;s Matrix Travels(网络流/费用流)

解题报告 题目传送门 题意: 从n×n的矩阵的左上角走到右下角,每次只能向右和向下走,走到一个格子上加上格子的数,可以走k次.问最大的和是多少. 思路: 建图:每个格子掰成两个点,分别叫"出点","入点", 入点到出点间连一个容量1,费用为格子数的边,以及一个容量∞,费用0的边. 同时,一个格子的"出点"向它右.下的格子的"入点"连边,容量∞,费用0. 源点向(0,0)的入点连一个容量K的边,(N-1,N-1)的出点向汇点连一

POJ训练计划2516_Minimum Cost(网络流/费用流)

解题报告 题意: 有n个商店,m个提供商,k种商品</span> n*k的矩阵,表示每个商店需要每个商品的数目: m*k矩阵,表示每个提供商拥有每个商品的个数 然后对于每个物品k,都有n*m的矩阵 i行j列表示 从j提供商向i商店运送一个k商品的代价是多少 判断所有的仓库能否满足所有客户的需求,如果可以,求出最少的运输总费用 思路: 建图的题,不能直接把所有信息建成图,因为n和m跟k都有关系,如果那样子建图的话,就要把k种拆成m类,每个仓库连向该仓库的第k种,然后再和n连线,有费用, 不过这样

POJ 2195 Going Home(网络流-费用流)

Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17777   Accepted: 9059 Description On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertical

POJ2135_Farm Tour(网络流/费用流)

解题报告 题目传送门 题意: 一个人有n个农场,他想从1到n去,有从n到1回来,要求路径最短,且没有走重复的路. 思路: 如果两次最短路感觉不行的,可以看成费用流,每一条路容量都是1,这样只要流量等于2就行了. 一次mcmf模版. #include <iostream> #include <cstring> #include <queue> #include <cstdio> #define inf 0x3f3f3f3f using namespace st

POJ训练计划2195_Going Home(网络流/费用流)

解题报告 题目传送门 思路: bfs建图跑一下费用流就行. #include <iostream> #include <cstdio> #include <cstring> #include <queue> #define inf 0x3f3f3f3f using namespace std; struct E { int v,cost,cap,next; } edge[100000]; int head[1000],cnt,dis[1000],pre[10

UVa10806_Dijkstra, Dijkstra.(网络流/费用流)(小白书图论专题)

解题报告 思路: 从s->t 再从t->s等同与s->t两次,要求每条路只能走一次,要求最小花费,让每一条边容量为1,跑跑费用流 只要跑出流量为2就结束. #include <iostream> #include <cstring> #include <cstdio> #include <queue> #define inf 0x3f3f3f3f #define N 5000 #define M 50000 using namespace

luogu P3381 【模板】最小费用最大流 |网络流费用流

#include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=1e4+10,M=2e5+10,inf=0x3f3f3f3f; int n,m,s,t; int nxt[M],head[N],go[M],edge[M],co

NEU 1458 方格取数(网络流之费用流)

题目地址:NEU 1458 跟杭电上的那两个方格取数不太一样..这个可以重复,但是取和的时候只能加一次.建图思路基本一会就出来.同样的拆点,只不过这题需要再拆个边,其中一条费用0,另一条费用为那个点处的值.流量都限制为1.然后剩下的都跟杭电上的那两个差不多了.因为把数组开小了WA了好几发..(我前面居然还专门检查了一下数组大小,居然当时还认为没开小...对自己无语..) 代码如下: #include <iostream> #include <stdio.h> #include &l