zoukankan      html  css  js  c++  java
  • 【BZOJ1305】 [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

    N<=50 K<=30

     
    把男孩女孩都拆点为x,y
    S向x连边,容量为a,y向汇点连边,容量为a
    a可以二分,可以枚举(反正只有30)
    男生x-->y连边为k,女生y-->x连边为k,男生喜欢女生在左部连边,反之在右部
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<iostream>
     5 using namespace std;
     6 const int inf=100000000,N=1005;
     7 struct ee{int to,next,f;}e[500001];
     8 int head[N],q[N*2],dis[N],map[N][N];
     9 int S,T,n,m,cnt=1,ans,w,k,mx;
    10    
    11 void ins(int u,int v,int f){
    12     e[++cnt].to=v;e[cnt].f=f;e[cnt].next=head[u];head[u]=cnt;
    13     e[++cnt].to=u;e[cnt].f=0;e[cnt].next=head[v];head[v]=cnt;
    14 }
    15    
    16 bool bfs(){
    17     for (int i=1;i<=T;i++) dis[i]=inf;
    18     int h=0,t=1,now;
    19     q[1]=S;dis[S]=0;
    20     while(h!=t){
    21         now=q[++h];
    22         for (int i=head[now];i;i=e[i].next){
    23             int v=e[i].to;
    24             if (e[i].f&&dis[now]+1<dis[v]){
    25                 dis[v]=dis[now]+1;
    26                 if (v==T)return 1;
    27                 q[++t]=v;
    28             }
    29         }
    30     }
    31     if (dis[T]==inf) return 0; return 1;
    32 }
    33    
    34 int dinic(int now,int f){
    35     if (now==T) return f;
    36     int rest=f;
    37     for (int i=head[now];i;i=e[i].next){
    38         int v=e[i].to;
    39         if (e[i].f&&dis[v]==dis[now]+1&&rest){
    40             int t=dinic(v,min(rest,e[i].f));
    41             if (!t) dis[v]=0;
    42             e[i].f-=t;
    43             e[i^1].f+=t;
    44             rest-=t;
    45         }
    46     }
    47     return f-rest;
    48 }
    49 void build(int f){
    50     cnt=1;
    51     memset(head,0,sizeof(head));
    52     for(int i=1;i<=n;i++) ins(S,i,f);
    53     for(int i=n+1;i<=2*n;i++) ins(i,T,f);
    54     for(int i=1;i<=n;i++) ins(i,i+2*n,k);
    55     for(int i=n+1;i<=2*n;i++) ins(i+2*n,i,k);
    56     for(int i=1;i<=n;i++)
    57         for(int j=1;j<=n;j++){
    58             if(map[i][j]) ins(i,j+n,1);
    59             else ins(i+2*n,j+3*n,1);
    60         } 
    61 }
    62 int main(){
    63     scanf("%d%d",&n,&k);
    64     T=4*n+1;
    65     char s[100];
    66     for(int i=1;i<=n;i++){
    67         scanf("%s",s+1);
    68         for(int j=1;j<=n;j++)
    69             if(s[j]=='Y') map[i][j]=1;
    70     }
    71     int l=0,r=50;
    72     while(l<=r)
    73     {
    74         int mid=(l+r)>>1;
    75         build(mid);
    76         ans=0;while(bfs()) ans+=dinic(S,inf);
    77         if(ans>=n*mid){mx=mid;l=mid+1;}
    78         else r=mid-1;
    79     }
    80     printf("%d",mx);
    81 } 
  • 相关阅读:
    LeetCode 1245. Tree Diameter
    LeetCode 1152. Analyze User Website Visit Pattern
    LeetCode 1223. Dice Roll Simulation
    LeetCode 912. Sort an Array
    LeetCode 993. Cousins in Binary Tree
    LeetCode 1047. Remove All Adjacent Duplicates In String
    LeetCode 390. Elimination Game
    LeetCode 1209. Remove All Adjacent Duplicates in String II
    LeetCode 797. All Paths From Source to Target
    LeetCode 1029. Two City Scheduling
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5211719.html
Copyright © 2011-2022 走看看