• [CQOI2009][BZOJ1305] dance跳舞


    1305: [CQOI2009]dance跳舞

    Time Limit: 5 Sec  Memory Limit: 162 MB
    Submit: 1877  Solved: 799
    [Submit][Status][Discuss]

    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

    N<=50 K<=30

    Source

     
    又是二分网络流……这几天真敲网络流敲恶心了。
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    #define MAXN 300
    #define MAXE 100000
    #define INF 100000007
    using namespace std;
    char c[100];
    int n,k,mx,T,tot,cnt,head[MAXN],dis[MAXN],q[MAXN];
    int next[MAXE],key0[MAXE],key[MAXE],list[MAXE];
    void insert(int x,int y,int z)
    {
        next[++tot]=head[x];
        head[x]=tot;
        list[tot]=y;
        key0[tot]=z;
    }
    void rebuild(int x)
    {
        for (int i=2;i<=cnt;i++)
            key[i]=key0[i];
        for (int i=cnt+1;i<=tot;i+=2)
            key[i]=x;
        for (int i=cnt+2;i<=tot;i+=2)
            key[i]=0;
    }
    bool BFS()
    {
        memset(dis,0xff,sizeof(dis));
        int t=0,w=1,x;
        dis[0]=1;q[1]=0;
        while (t<w)
        {
            x=q[++t];
            for (int i=head[x];i;i=next[i])
                if (key[i]&&dis[list[i]]==-1)
                {
                    dis[list[i]]=dis[x]+1;
                    q[++w]=list[i];
                }
        }
        return dis[T]!=-1;
    }
    int find(int x,int flow)
    {
        if (x==T) return flow;
        int used=0,w;
        for (int i=head[x];i;i=next[i])
            if (key[i]&&dis[list[i]]==dis[x]+1)
            {
                                                w=find(list[i],min(key[i],flow-used));
                                                key[i]-=w;
                                                key[i^1]+=w;
                                                used+=w;
                                                if (used==flow) return flow;
            }
        if (!used) dis[x]=-1;
        return used;
    }
    bool dinic(int x)
    {
        int ans=0;
        while (BFS()) ans+=find(0,INF);
        if (ans>=x*n) return 1; return 0;
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        T=4*n+1;
        tot=1;
        for (int i=1;i<=n;i++) 
        {
            scanf("%s",c);
            for (int j=0;j<n;j++)
                if (c[j]=='Y') 
                {
                    insert(i,j+1+3*n,1);
                    insert(j+1+3*n,i,0);
                }
                else 
                {
                    insert(i+n,j+1+2*n,1);
                    insert(j+1+2*n,i+n,0);
                }
        }
        for (int i=1;i<=n;i++)
        {
            insert(i,i+n,k);
            insert(i+n,i,0);
            insert(i+2*n,i+3*n,k);
            insert(i+3*n,i+2*n,0);
        }
        cnt=tot;
        for (int i=1;i<=n;i++)
        {
            insert(0,i,0);
            insert(i,0,0);
            insert(i+3*n,T,0);
            insert(T,i+3*n,0);
        }
        int l=0,r=n;
        while (l<=r)
        {
            int mid=(l+r)>>1;
            rebuild(mid);
            if (dinic(mid)) 
            {
                mx=mid;
                l=mid+1;
            }
            else r=mid-1;
        }
        printf("%d",mx);
        return 0;
    }
  • 相关阅读:
    sublime生成html快捷标签布局
    vue.js选项卡动态组件
    textarea内容限制字数
    60s验证等待
    vue.js显示隐藏
    CSS强制性换行
    Ultra Pull To Refresh下拉刷新
    Open经验库网址
    Fresco实例
    解决LinearLayout中控件不能居右对齐
  • 原文地址:https://www.cnblogs.com/ws-fqk/p/4659300.html
Copyright © 2020-2023  润新知