zoukankan      html  css  js  c++  java
  • 网络流(费用流)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 3
    ATK 2000
    DEF 1700
    2500
    2500
    2500
    Output
    3000
    Input
    3 4
    ATK 10
    ATK 100
    ATK 1000
    1
    11
    101
    1001
    Output
    992
    Input
    2 4
    DEF 0
    ATK 0
    0
    0
    1
    1
    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
    ",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
    ",McMf(S,T));
    81     return 0;
    82 }    
  • 相关阅读:
    2020毕业设计选用4412开发板,实战教程,小成果不放过
    学习嵌入式有决心4412再送免费教程
    iTOP4412开发板can测试工具使用文档
    iTOP4412Ubuntu系统源码ubuntu没有声音的解决办法
    修身养性,为人处事100条
    用X++实现有规律分割的长字符串,分别提取(如逗号隔开)
    自定义Dialog中对数组的取值
    Common实现任何Form定位查询转到当前Form种过滤符合条件的数据区域
    用X++得到当前用户是否有某Security Key的权限级别,完整Job演示
    获取table中的系统字段信息
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5928251.html
Copyright © 2011-2022 走看看