[luogu 3701] 「伪模板」主席树 {dinic网络流}

版权声明:~~~感谢支持! https://blog.csdn.net/qq_39897867/article/details/88874962

题目

https://www.luogu.org/problemnew/show/P3701


解题思路

题目中这样的提示-->网络流

这五种人的输赢如上图所示(一样的人不能PK),箭头指向输的人。至于为什么,留给同学们自己思考。

我们可以将源点和byx的人连容量为生命值的边,汇点也是一样(跟手气君连边)。

注意yyy的数量也加到自身团队里的J和源点(或汇点)连接的边的容量上很显然,肯定不能让yyy先死啦!!!

我就是因为这个原因找了很久的错误在套了网络流dinic的模板后,注意最后答案要 m i n ( a n s , m ) min(ans,m)


代码

#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)); 
}

猜你喜欢

转载自blog.csdn.net/qq_39897867/article/details/88874962
今日推荐