BZOJ 1305 [CQOI2009]dance跳舞

这是一道最大流的模版题

一定要记住不能开出来重点呀

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=205;
const int MAXM=6005;
const int inf=0x3f3f3f3f;
inline int read(){
    int x=0,f=1,ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline int cread(){
    int ch=getchar();
    while(ch<'A'||ch>'Z') ch=getchar();
    return ch;
}
int nxt[MAXM],to[MAXM],cap[MAXM],h[MAXN],cnt;
inline void add(int x,int y,int k){
    nxt[cnt]=h[x];to[cnt]=y;cap[cnt]=k;h[x]=cnt++;
    nxt[cnt]=h[y];to[cnt]=x;cap[cnt]=0;h[y]=cnt++;
}
int dep[MAXN];
queue<int> q;
inline bool bfs(int s,int t){
    // cout<<s<<"\t"<<t<<endl;
    while(!q.empty()) q.pop();
    memset(dep,0,sizeof(dep));
    dep[s]=1;q.push(s);
    while(!q.empty()){
        int e=q.front();q.pop();
        for(int i=h[e];i!=-1;i=nxt[i])
            if(cap[i]&&dep[to[i]]==0)
                dep[to[i]]=dep[e]+1,q.push(to[i]);
    }
    return dep[t]?1:0;
}
int T;
inline int dfs(int x,int k){
    if(x==T) return k;
    int res=0;
    for(int i=h[x];i!=-1&&k;i=nxt[i])
        if(cap[i]&&dep[to[i]]==dep[x]+1){
            int d=dfs(to[i],min(k,cap[i]));
            if(d) cap[i]-=d,cap[i^1]+=d,res+=d,k-=d;
        }
    if(!res) dep[x]=0;
    return res;
}
int n,k;
inline int dinic(){
    int res=0;T=(n+1)<<2;
    while(bfs(0,T)) res+=dfs(0,inf);
    return res;
}
int map[55][55];
inline bool ok(int x){
    memset(h,-1,sizeof(h));
    cnt=0;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j){
            if(map[i][j]) add(i<<1,(j+n)<<1,1);
            else add(i<<1|1,(j+n)<<1|1,1);
        }
    for(int i=1;i<=n;++i) add(0,i<<1,x),add((i+n)<<1,(n+1)<<2,x);
    for(int i=1;i<=n;++i) add(i<<1,i<<1|1,k),add((i+n)<<1|1,(i+n)<<1,k);
    return (dinic()>=x*n);
}
int main(){
    n=read(),k=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j){
            int c=cread();
            if(c=='Y') map[i][j]=1;
        }
    int l=0,r=n;
    while(l<r){
        // cout<<l<<"\t"<<r<<endl;
        int mid=(l+r)>>1;
        if(ok(mid+1)) l=mid+1;
        else r=mid;
    }
    printf("%d\n",l);
    return 0;
}

  

posted @ 2018-12-03 14:49  古城独钓  阅读(100)  评论(0编辑  收藏  举报