版权声明:~~~感谢支持! https://blog.csdn.net/qq_39897867/article/details/88874962
题目
https://www.luogu.org/problemnew/show/P3701
解题思路
题目中这样的提示-->网络流
:
这五种人的输赢如上图所示(一样的人不能PK),箭头指向输的人。至于为什么,留给同学们自己思考。
我们可以将源点和byx的人连容量为生命值的边,汇点也是一样(跟手气君连边)。
注意yyy的数量也加到自身团队里的J和源点(或汇点)连接的边的容量上很显然,肯定不能让yyy先死啦!!!
我就是因为这个原因找了很久的错误
在套了网络流dinic的模板后,注意最后答案要
代码
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#define rep(i,x,y) for (register int i=x;i<=y;++i)
using namespace std;
const int N=510,M=10010,inf=1e9;
struct node{int to,w,next;}a[M];
int tot=1,n,m,qw,gw,ans,dep[N],head[N],s,t,l,d;
char c[N][30],b[N][30];
queue<int> q;
void add(int x,int y,int z){
a[++tot]=(node){y,z,head[x]}; head[x]=tot;
a[++tot]=(node){x,0,head[y]}; head[y]=tot;
}
bool bfs()
{
memset(dep,0,sizeof(dep));
while(!q.empty()) q.pop();
q.push(s);dep[s]=1;
while(!q.empty()){
int x=q.front();q.pop();
for(register int i=head[x];i;i=a[i].next){
int y=a[i].to;
if(!dep[y]&&a[i].w){
dep[y]=dep[x]+1;
if(y==t) return 1;
q.push(y);
}
}
}
return 0;
}
int dinic(int x,int flow)
{
int rest=0,k;
if(x==t) return flow;
for(register int i=head[x];i;i=a[i].next){
int y=a[i].to;
if(dep[x]+1==dep[y]&&a[i].w){
rest+=(k=dinic(y,min(a[i].w,flow-rest)));
a[i].w-=k;a[i^1].w+=k;
if(rest==flow) return flow;
}
}
if (!rest) dep[x]=0;
return rest;
}
int main(){
freopen("lw.txt","r",stdin);
scanf("%d%d",&n,&m),s=n*2+1,t=n*2+2;
rep(i,1,n) {
cin>>c[i];
if (c[i][0]=='Y') qw++;
}
rep(i,1,n) {
cin>>b[i];
if (b[i][0]=='Y') gw++;
}
rep(i,1,n) {
scanf("%d",&d);
if (c[i][0]=='J') add(s,i,d+qw); else add(s,i,d);
}
rep(i,1,n) {
scanf("%d",&d);
if (b[i][0]=='J') add(i+n,t,d+gw); else add(i+n,t,d);
}
rep(i,1,n) rep(j,1,n)
if (c[i][0]=='W'&&b[j][0]=='Y') add(i,j+n,1); else
if (c[i][0]=='W'&&b[j][0]=='E') add(i,j+n,1); else
if (c[i][0]=='J'&&b[j][0]=='W') add(i,j+n,1); else
if (c[i][0]=='J'&&b[j][0]=='H') add(i,j+n,1); else
if (c[i][0]=='E'&&b[j][0]=='Y') add(i,j+n,1); else
if (c[i][0]=='E'&&b[j][0]=='J') add(i,j+n,1); else
if (c[i][0]=='Y'&&b[j][0]=='J') add(i,j+n,1); else
if (c[i][0]=='Y'&&b[j][0]=='H') add(i,j+n,1); else
if (c[i][0]=='H'&&b[j][0]=='E') add(i,j+n,1); else
if (c[i][0]=='H'&&b[j][0]=='W') add(i,j+n,1);
while (bfs()) ans+=dinic(s,inf);
return 0&printf("%d",min(ans,m));
}