版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugar_free_mint/article/details/82788518
题目
给出一些敌对关系,主席的生命需加上膜法师的数量,每打斗一次减一条命,一共打m场,问一共能打赢多少场
分析
可以发现题目其实是求最大匹配,这样理解就比较容易了,样例解释图
代码
#include <cstdio>
#include <vector>
#include <queue>
#define rr register
#define r(i,a,b) for (rr int i=a;i<=b;i++)
#define min(a,b) ((a)<(b))?(a):(b)
using namespace std;
struct node{
int y,w,next;
}e[10001];
int a[101],b[101],c[101],d[101],ls[201],dis[201];
vector<int>p[6]; int n,m,s,t,k=1,ans;
inline int in(){
rr int ans=0; rr char c=getchar();
while (c<48||c>57) c=getchar();
while (c>47&&c<58) ans=(ans<<3)+(ans<<1)+c-48,c=getchar();
return ans;
}
inline int read(){
rr char c=getchar(); rr int ans;
while (c<65||c>90) c=getchar();
if (c=='J') ans=1;
if (c=='H') ans=2;
if (c=='W') ans=3;
if (c=='Y') ans=4;
if (c=='E') ans=5;
while (c>64&&c<91) c=getchar();
return ans;
}
inline void add(int x,int y,int w){
e[++k]=(node){y,w,ls[x]}; ls[x]=k;
e[++k]=(node){x,0,ls[y]}; ls[y]=k;
}
inline bool bfs(int s){
r(i,1,t) dis[i]=0;
rr queue<int>q;
q.push(s); dis[s]=1;
while (q.size()){
rr int x=q.front(); q.pop();
for (rr int i=ls[x];i;i=e[i].next)
if (e[i].w>0&&!dis[e[i].y]){
dis[e[i].y]=dis[x]+1;
if (e[i].y==t) return 1;
q.push(e[i].y);
}
}
return 0;
}
inline int dfs(int x,int now){
if (x==t||!now) return now;
rr int rest=0,f;
for (rr int i=ls[x];i;i=e[i].next)
if (e[i].w>0&&dis[e[i].y]==dis[x]+1){
rest+=(f=dfs(e[i].y,min(now-rest,e[i].w)));
e[i].w-=f; e[i^1].w+=f;
if (now==rest) return rest;
}
if (!rest) dis[x]=0;
return rest;
}
int main(){
n=in(); rr int m=in(),cnt=0; s=n<<1|1; t=s+1;
r(i,1,n) a[i]=read(); r(i,1,n) b[i]=read();
r(i,1,n) c[i]=in(); r(i,1,n) d[i]=in();
r(i,1,n) cnt+=a[i]==4; r(i,1,n) c[i]+=a[i]==1?cnt:0; cnt=0;
r(i,1,n) cnt+=b[i]==4; r(i,1,n) d[i]+=b[i]==1?cnt:0;//主席加上膜法师的数量(补血)
r(i,1,n) add(s,i,c[i]),add(i+n,t,d[i]);
r(i,1,n) p[b[i]].push_back(i);
r(i,1,n)//敌对关系建图
if (a[i]==1){
if (p[2].size()) r(j,0,p[2].size()-1) add(i,p[2][j]+n,1);
if (p[3].size()) r(j,0,p[3].size()-1) add(i,p[3][j]+n,1);
}
else if (a[i]==2){
if (p[3].size()) r(j,0,p[3].size()-1) add(i,p[3][j]+n,1);
if (p[5].size()) r(j,0,p[5].size()-1) add(i,p[5][j]+n,1);
}
else if (a[i]==3){
if (p[4].size()) r(j,0,p[4].size()-1) add(i,p[4][j]+n,1);
if (p[5].size()) r(j,0,p[5].size()-1) add(i,p[5][j]+n,1);
}
else if (a[i]==4){
if (p[1].size()) r(j,0,p[1].size()-1) add(i,p[1][j]+n,1);
if (p[2].size()) r(j,0,p[2].size()-1) add(i,p[2][j]+n,1);
}
else if (a[i]==5){
if (p[1].size()) r(j,0,p[1].size()-1) add(i,p[1][j]+n,1);
if (p[4].size()) r(j,0,p[4].size()-1) add(i,p[4][j]+n,1);
}
while (bfs(s)){//最大流
ans+=dfs(s,1e9);
if (ans>m) return !printf("%d",m);
}
return !printf("%d",ans);
}