• 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

     
    题解:
    将男生i拆为两个点i1,i2,将女生j也拆为j1,j2,如果i和j互相喜欢,则由i1到j1连一条容量为1的边,否则由i2到j2连一条容量为1的边
    对于男生i,由i1向i2连一条容量为k的边,对于女生j,由j2向j1连一条容量为k的边
    然后二分次数tim,由S向每个男生i1连容量为tim的边,由每个女生j1向T连容量为tim的边,然后如果最大流=tim*n,则这个次数可行
    code:
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #define maxn 250
     7 #define maxm 6000
     8 #define inf 1061109567
     9 using namespace std;
    10 char ch;
    11 bool ok;
    12 void read(int &x){
    13     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    14     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    15     if (ok) x=-x;
    16 }
    17 char g[55][55];
    18 int n,k,l,r,m;
    19 struct flow{
    20     int s,t,tot,now[maxn],son[maxm],pre[maxm],val[maxm];
    21     int dis[maxn],head,tail,list[maxn];
    22     bool bo[maxn];
    23     void init(){s=0,t=1,tot=1,memset(now,0,sizeof(now));}
    24     void put(int a,int b,int c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
    25     void add(int a,int b,int c){put(a,b,c),put(b,a,0);}
    26     bool bfs(){
    27         memset(bo,0,sizeof(bo));
    28         head=0,tail=1,list[1]=s,dis[s]=0,bo[s]=1;
    29         while (head<tail){
    30             int u=list[++head];
    31             for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
    32                 if (val[p]&&!bo[v]) bo[v]=1,dis[v]=dis[u]+1,list[++tail]=v;
    33         }
    34         return bo[t];
    35     }
    36     int dfs(int u,int rest){
    37         if (u==t) return rest;
    38         int ans=0;
    39         for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p])
    40             if (val[p]&&dis[v]==dis[u]+1){
    41                 int d=dfs(v,min(rest,val[p]));
    42                 val[p]-=d,val[p^1]+=d,ans+=d,rest-=d;
    43             }
    44         if (!ans) dis[u]=-1;
    45         return ans;
    46     }
    47     int dinic(){
    48         int ans=0;
    49         while (bfs()) ans+=dfs(s,inf);
    50         return ans;
    51     }
    52 }f,tmp;
    53 bool check(int lim){
    54     f=tmp;
    55     for (int i=1;i<=n;i++) f.add(f.s,i<<1,lim);
    56     for (int i=1;i<=n;i++) f.add((i+n)<<1,f.t,lim);
    57     return f.dinic()==lim*n;
    58 }
    59 int main(){
    60     read(n),read(k),f.init();
    61     for (int i=1;i<=n;i++) scanf("%s",g[i]+1);
    62     for (int i=1;i<=n;i++) f.add(i<<1,(i<<1)+1,k);
    63     for (int i=1;i<=n;i++) f.add(((i+n)<<1)+1,(i+n)<<1,k);
    64     for (int i=1;i<=n;i++) for (int j=1;j<=n;j++)
    65         if (g[i][j]=='Y') f.add(i<<1,(j+n)<<1,1);
    66         else f.add((i<<1)+1,((j+n)<<1)+1,1);
    67     for (tmp=f,l=0,r=n,m=((l+r)>>1)+1;l<r;m=((l+r)>>1)+1) if (check(m)) l=m; else r=m-1;
    68     printf("%d
    ",l);
    69     return 0;
    70 }
  • 相关阅读:
    Struts2 helloWorld
    Python学习笔记基础汇总部分
    从控制台读入,典型的装饰者模式
    随机数产生方法小知识点
    Struts2基础知识
    面向对象原则之GOF是招式,九大原则才是精髓
    静态工厂方法
    单例模式singleton
    J2SE基础夯实系列之JDBC,链接数据库实例代码
    Ubuntu 12.04 下安装ssh 服务遇到的问题以及总结
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/5138288.html
Copyright © 2020-2023  润新知