zoukankan      html  css  js  c++  java
  • [BZOJ1305][CQOI2009]跳舞(网络流)

    1305: [CQOI2009]dance跳舞

    Time Limit: 5 Sec  Memory Limit: 162 MB
    Submit: 3944  Solved: 1692
    [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

    [Submit][Status][Discuss]

    显然是一个二分图匹配的问题,将每个人拆成两个点:喜欢点i和讨厌点i',每个限制依次考虑:

    1.一对只跳一次:喜欢则i和j连1的边,讨厌则i'和j'连1的边。

    2.讨厌至多k个:i向i'连k的边,j'向j连k的边。

    3.但是这样直接跑之后并不能得到结果,因为不保证同性之间没有冲突,所以必须二分答案mid,S向i连mid边,j向T连mid边。

    跑$O(log n)$次最大流即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define rep(i,l,r) for (int i=l; i<=r; i++)
     5 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
     6 using namespace std;
     7 
     8 const int N=1010,M=500100,inf=0x3f3f3f3f;
     9 char ch;
    10 int n,k,cnt,ans,mx,mid,S,T,d[N],q[M],h[N],f[M],nxt[M],to[M],mp[N][N];
    11 
    12 void add(int u,int v,int w){
    13     to[++cnt]=v; f[cnt]=w; nxt[cnt]=h[u]; h[u]=cnt;
    14     to[++cnt]=u; f[cnt]=0; nxt[cnt]=h[v]; h[v]=cnt;
    15 }
    16 
    17 int bfs(){
    18     rep(i,0,T) d[i]=0; d[S]=1; q[1]=S;
    19     for (int st=0,ed=1; st!=ed; ){
    20         int x=q[++st];
    21         For(i,x) if (!d[k=to[i]] && f[i]) q[++ed]=k,d[k]=d[x]+1;
    22     }
    23     return d[T];
    24 }
    25 
    26 int dfs(int x,int lim){
    27     if (x==T) return lim;
    28     int c=0,t;
    29     For(i,x) if (d[k=to[i]]==d[x]+1 && f[i]){
    30         t=dfs(k,min(lim-c,f[i]));
    31         f[i]-=t; f[i^1]+=t; c+=t;
    32         if (c==lim) return lim;
    33     }
    34     if (!c) d[x]=-1;
    35     return c;
    36 }
    37 
    38 void build(){
    39     cnt=1; memset(h,0,sizeof(h));
    40     S=4*n+1,T=4*n+2;
    41     rep(i,1,n) add(S,i,mid),add(i,i+n,k),add(i+2*n,i+3*n,k),add(i+3*n,T,mid);
    42     rep(i,1,n) rep(j,1,n) if (mp[i][j]) add(i,j+3*n,1); else add(i+n,j+2*n,1);
    43 }
    44 
    45 int main(){
    46     freopen("bzoj1305.in","r",stdin);
    47     freopen("bzoj1305.out","w",stdout);
    48     scanf("%d%d",&n,&k);
    49     rep(i,1,n) rep(j,1,n) scanf(" %c",&ch),mp[i][j]=(ch=='Y');
    50     int L=0,R=n;
    51     while (L<=R){
    52         mid=(L+R)>>1; build();
    53         ans=0; while (bfs()) ans+=dfs(S,inf);
    54         if (ans>=n*mid) mx=mid,L=mid+1; else R=mid-1;
    55     }
    56     printf("%d
    ",mx);
    57     return 0;
    58 }
  • 相关阅读:
    安卓开发知识点
    安卓开发第一天之环境搭建
    maven中的依赖的范围、传递、冲突,继承
    pom.xml文件
    Maven的目录结构
    tomcat的端口修改不成功
    maven的安装和配置,及在Eclipse里的使用
    servlet的路径跳转及路径问题
    servlet如何获取jsp表单里的数据
    关于“servelt始终驻留在服务器内存”的理解
  • 原文地址:https://www.cnblogs.com/HocRiser/p/8781523.html
Copyright © 2011-2022 走看看