• BZOJ 1305: [CQOI2009]dance跳舞 二分+最大流


    1305: [CQOI2009]dance跳舞


    Description

    一次舞会有n个男孩和n个女孩。每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞。每个男孩都不会和同一个女孩跳两首(或更多)舞曲。有一些男孩女孩相互喜欢,而其他相互不喜欢(不会“单向喜欢”)。每个男孩最多只愿意和k个不喜欢的女孩跳舞,而每个女孩也最多只愿意和k个不喜欢的男孩跳舞。给出每对男孩女孩是否相互喜欢的信息,舞会最多能有几首舞曲?

    Input

    第一行包含两个整数n和k。以下n行每行包含n个字符,其中第i行第j个字符为'Y'当且仅当男孩i和女孩j相互喜欢。

    Output

    仅一个数,即舞曲数目的最大值。

    Sample Input

    3 0
    YYY
    YYY
    YYY

    Sample Output

    3

    HINT

    题解:

      建图:

      男女分别拆点x,y

      男生拆点后 有x1,x2两种,女生拆点后又y1,y2

        S - x1( 连向喜欢的人的点 )-> y1 ->T

     容量k   |             |

          x2(连向不喜欢的人的点)->y2

       其余容量为1

      二分答案,从S流出的每条边容量为mid,check 是否满流

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    const long long INF = 1e18+1LL;
    const double Pi = acos(-1.0);
    const int N = 100000, M = 1e3+20, mod = 1e9+7, inf = 2e9;
    char mp[100][100];
    int n,k,head[N],t=2,h[N],q[N],S,T,ans;
    struct edge{int to,next,v;}e[N * 2];
    void adds(int u,int v,int w) {e[t].to=v;e[t].v=w;e[t].next=head[u];head[u]=t++;}
    void add(int u,int v,int w) {adds(u,v,w);adds(v,u,0);}
    int bfs() {
        memset(h,-1,sizeof(h));
        int l=0,r=1,now;
        q[l]=S;
        h[S]=0;
        while(l!=r){
            now=q[l++];if(l == 10000) l=0;
            for(int i=head[now];i!=-1;i=e[i].next) {
                if(e[i].v&&h[e[i].to]==-1) {
                    h[e[i].to]=h[now]+1;
                    q[r++]=e[i].to;
                    if(r==10000) r = 0;
                }
            }
        }
        if(h[T]==-1) return 0;
        else return 1;
    }
    int dfs(int x,int f) {
            if(x == T) return f;
            int used=0,w;
            for(int i=head[x]; i!=-1;i=e[i].next) {
                if(e[i].v&&h[e[i].to] == h[x] + 1) {
                    w=dfs(e[i].to,min(f-used,e[i].v));
                    used+=w;e[i].v-=w;e[i^1].v+=w;
                    if(used == f) return f;
                }
            }
            return used;
    }
    void dinic() {while(bfs()) ans+=dfs(S,inf);}
    
    int check(int x) {
        t = 2;S = 4*n+1, T = S+1;
        memset(head,-1,sizeof(head));
            for(int i=1;i<=n;++i) {
                add(S,i,x);
                add(i,i+n,k);
                add(2*n+i+n,i+2*n,k);
                add(2*n+i,T,x);
            }
            for(int i=1;i<=n;++i) {
                for(int j=1;j<=n;++j) {
                    if(mp[i][j] == 'Y') {
                        add(i,2*n+j,1);
                    }
                    else add(i+n,2*n+n+j,1);
                }
            }ans = 0;
            dinic();
            if(ans == n*x) return 1;
            else return 0;
    }
    int main() {
            scanf("%d%d",&n,&k);
            for(int i=1;i<=n;++i) scanf("%s",mp[i]+1);
            int l = 0, r = n,ans1;
            while(l <= r) {
                int md = (l+r)>>1;
                if(check(md)) {
                    ans1 = md;l = md+1;
                } else r = md-1;
            }
            printf("%d
    ",ans1);
            return 0;
    }
    View Code
  • 相关阅读:
    SQLServer之视图简介
    几种快速以伺服静态文件的方法
    Node.js静态文件服务器实战[转]
    mac ssh中文乱码解决
    SSH上传和下载文件
    在web项目中集成pdf.js的默认查看器
    用pip批量更新所有包
    C# 异步锁【转】
    .NET 4并行编程入门之Task的取消[转]
    VIM技巧:选择文本块
  • 原文地址:https://www.cnblogs.com/zxhl/p/6134367.html
Copyright © 2020-2023  润新知