跳舞

简单题。
看代码。

#include<bits/stdc++.h>
using namespace std;
#define N 200010
#define M 200010
int h[M],nxt[M],v[M],w[M],s,t,dep[M],ec,n,k;
char st[1000][1000];
void add(int a,int b,int c){v[++ec]=b;w[ec]=c;nxt[ec]=h[a];h[a]=ec;}
void adj(int a,int b,int c){
	add(a,b,c);
	add(b,a,0);
}
bool bfs(){
    queue<int>q;
	q.push(s);
    for(int i=0;i<=t;i++)
    	dep[i]=0;
	dep[s]=1;
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=h[x];i;i=nxt[i])
            if(w[i]&&!dep[v[i]]){
            	dep[v[i]]=dep[x]+1;
				q.push(v[i]);
            	if(v[i]==t)
					return 1;
			}
    }
	return 0;
}
int dfs(int x,int dis){
    if(x==t)
		return dis;
	int tp=dis;
    for(int i=h[x];i;i=nxt[i])
        if(dep[v[i]]==dep[x]+1&&w[i]){
            int f=dfs(v[i],min(tp,w[i]));
            if(!f)
				dep[v[i]]=0;
            tp-=f;
            w[i]-=f;
			w[i^1]+=f;
            if(!tp)
				break;
        }
    return dis-tp;
}
int din(){
    int aans=0;
    while(bfs()){
    	int v;
    	while(v=dfs(s,1e9))
			aans+=v;
	}
    return aans;
}
int pd(int x){
	ec=1;
	memset(h,0,sizeof(h));
	t=6*n+5;
	for(int i=1;i<=n;i++)
		adj(s,i,x);
	for(int i=1;i<=n;i++){
		adj(i,i+n,1e9);
		adj(i,i+n*2,k);
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++){
			if(st[i][j]=='Y')
				adj(i+n,j+3*n,1);
			else
				adj(i+2*n,j+4*n,1);
		}
	for(int i=1;i<=n;i++){
		adj(i+3*n,i+5*n,1e9);
		adj(i+4*n,i+5*n,k);
	}
	for(int i=1;i<=n;i++)
		adj(i+5*n,t,x);
	if(din()==n*x)
		return 1;
	return 0;
}
signed main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
		scanf("%s",st[i]+1);
	int l=1,r=n,ans=0;
	while(l<=r){
		int md=(l+r)/2;
		if(pd(md)){
			l=md+1;
			ans=md;
		}
		else
			r=md-1;
	}
	printf("%d",ans);
}


原文地址:https://www.cnblogs.com/ctmlpfs/p/14969980.html