zoukankan      html  css  js  c++  java
  • 【BZOJ1305】【CQOI2009】 dance跳舞

    看menci的博客点出二分的思路然后做出来,menci太强辣

    原题:

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

    N<=50 K<=30

    看榜上的都是0MS,这是什么神奇的做法

    先看menci的博客发现这道题,知道是网络流,想了一段时间无果,回menci的博客看了一眼,然后发现两个字

    "二分"

    然后思路就想出来了,二分答案,根据答案建图然后验证是否能跑到满流

    具体建图方法就很简答了,相互喜欢的男女权值为1,每个男女要额外一个点来保证和不喜欢的人的限制,本来的点和额外的点中间权值为k,两个不喜欢的男女之间额外的点权值为1,源到男,女到汇权值为二分的答案

    如果能跑到满流就说明答案和法

    另外有一点需要注意就是二分的下线要从0开始,因为可能会无解

    二分也是转换问题很关键的方式,以后想题还要尽量考虑一下

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<vector>
     7 using namespace std;
     8 const int oo=168430090;
     9 int rd(){int z=0,mk=1;  char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
    11     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    12     return z*mk;
    13 }
    14 struct ddd{int y,v,re;};  vector <ddd> e[210];
    15 inline void ist(int x,int y,int z){
    16     e[x].push_back((ddd){y,z,e[y].size()});
    17     e[y].push_back((ddd){x,0,e[x].size()-1});
    18 }
    19 int n,m;  int s,t;  int n2,n3,n4;
    20 char a[60][60];
    21 int lvl[210];
    22 int q[210],hd=0;
    23 void clear(){  for(int i=s;i<=t;++i)  e[i].clear();}
    24 bool gtlvl(){
    25     memset(lvl,0,sizeof(lvl));
    26     q[hd=1]=s,lvl[s]=1;
    27     int x,sz;
    28     for(int k=1;k<=hd;++k){
    29         x=q[k],sz=e[x].size();
    30         for(int i=0;i<sz;++i)if(e[x][i].v && !lvl[e[x][i].y])
    31             lvl[e[x][i].y]=lvl[x]+1,q[++hd]=e[x][i].y;
    32     }
    33     return lvl[t];
    34 }
    35 int agmt(int x,int y){
    36     if(x==t)  return y;
    37     int mxflw=0,flw,sz=e[x].size();
    38     for(int i=0;i<sz && mxflw<y;++i)if(lvl[e[x][i].y]==lvl[x]+1 && e[x][i].v)
    39         if(flw=agmt(e[x][i].y,min(y-mxflw,e[x][i].v))){
    40             mxflw+=flw;
    41             e[x][i].v-=flw,e[e[x][i].y][e[x][i].re].v+=flw;
    42         }
    43     if(!mxflw)  lvl[x]=0;
    44     return mxflw;
    45 }
    46 int dnc(){
    47     int bwl=0,flw;
    48     while(gtlvl())while(flw=agmt(s,oo))  bwl+=flw;
    49     return bwl;
    50 }
    51 bool chck(int x){
    52     clear();
    53     for(int i=1;i<=n;++i){
    54         for(int j=1;j<=n;++j){
    55             if(a[i][j]=='Y')  ist(i,j+n3,1);
    56             else  ist(i+n,j+n2,1);
    57         }
    58         ist(i,i+n,m),ist(i+n2,i+n3,m);
    59         ist(s,i,x),ist(i+n3,t,x);
    60     }
    61     return dnc()==x*n;
    62 }
    63 int bnrsch(){
    64     int l=0,r=n,md;
    65     while(l+1<r){  md=(l+r)>>1;  (chck(md)?l:r)=md;}
    66     return chck(r)?r:l;
    67 }
    68 int main(){//freopen("ddd.in","r",stdin);
    69     cin>>n>>m;  n2=n*2,n3=n*3,n4=n*4;  s=0,t=n4+1;
    70     /*for(int i=1;i<=n;++i){
    71         scanf("%s",s+1);
    72         for(int j=1;j<=n;++j){
    73             if(s[j]=='Y')  ist(i,j+3n,1);
    74             else  ist(i+n,j+2n,1);
    75         }
    76         ist(i,i+n,k),ist(i+2n,i+3n,k);*/
    77     for(int i=1;i<=n;++i)  scanf("%s",a[i]+1);
    78     cout<<bnrsch()<<endl;
    79     return 0;
    80 }
    View Code
  • 相关阅读:
    C#_委托
    一个asp+ACCESS省市二级联动菜单程序
    asp怎么实现二级联动下拉菜单
    ASP用户登录代码
    Windows 2003 IIS 不支持ASP的问题
    iptables
    VNC ( Virtual Network Computing )
    MongoDB的备份(mongodump)与恢复(mongorestore)
    Locally managed (LMT) vs. Dictionary managed (DMT) tablespace
    向现有的磁盘组加入/删除ASM磁盘
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6435615.html
Copyright © 2011-2022 走看看