传送门->

又是陈年老坑。

听上去不知道从何下【手】?那要是把题目换成“判断这些人能否条x支舞”呢?

这样就变成了一个网络流可以解决的问题,只要把每个人拆成喜欢和不喜欢两点,每个人两点总流量不超过x,喜欢的人之间的连边是x,不喜欢的人之间连边为k,最后通过判断是否每个人总流量流满就行。

会发现x越大,越难以流满,有单调性,那就可以二分了。

#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define re register
#define maxn 510
#define maxm 500010
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(isdigit(ch)==0 && ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(int x)
{
int f=0;char ch[20];
if(!x){puts("0");return;}
if(x<0){putchar('-');x=-x;}
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar('\n');
}
int n,K,fir[maxn],nxt[maxm],v[maxm],fl[maxm],dis[maxn],maxflow,cnt,l,r,ans,s,t,inf[3];
char yes[60][60];
queue<int >q;
void ade(int u1,int v1,int fl1)
{
v[cnt]=v1,fl[cnt]=fl1,nxt[cnt]=fir[u1],fir[u1]=cnt++;
v[cnt]=u1,fl[cnt]=0,nxt[cnt]=fir[v1],fir[v1]=cnt++;
}
void reset(){memset(fir,-1,sizeof(fir)),maxflow=cnt=0;}
int bfs()
{
memset(dis,-1,sizeof(dis));
dis[t]=0;q.push(t);
while(!q.empty())
{
int u=q.front();q.pop();
for(int k=fir[u];k!=-1;k=nxt[k])
{
int vv=v[k];
if(fl[k^1]&&dis[vv]==-1)
{
dis[vv]=dis[u]+1;
q.push(vv);
}
}
}
return dis[s]==-1?0:1;
}
int dfs(int u,int nowflow)
{
if(u==t||!nowflow)return nowflow;
int tmp,sum=0;
for(int k=fir[u];k!=-1;k=nxt[k])
{
if(!nowflow)break;
int vv=v[k];
if(dis[vv]+1==dis[u]&&fl[k]&&(tmp=dfs(vv,min(fl[k],nowflow)))>0)
fl[k]-=tmp,fl[k^1]+=tmp,nowflow-=tmp,sum+=tmp;
}
return sum;
}
int check(int tim)
{
s=0,t=n*4+1;
rep(i,1,n)ade(s,i,tim),ade(i,i+n,K),ade(i+n*2,t,tim),ade(i+n*3,i+n*2,K);
rep(i,1,n)
rep(j,1,n)
{
if(yes[i][j]=='Y')ade(i,j+n*2,1);
else ade(i+n,j+n*3,1);
}
while(bfs())maxflow+=dfs(s,inf[0]);
return (maxflow==n*tim);
}
int main()
{
memset(inf,0x7f,sizeof(inf));
n=read(),K=read();
rep(i,1,n){scanf("%s",yes[i]+1);}
l=0,r=n;
while(l<=r)
{
reset();
int mid=(l+r)>>1;
if(check(mid))ans=mid,l=mid+1;
else r=mid-1;
}
write(ans);
return 0;
}

  

最新文章

  1. MMORPG大型游戏设计与开发(客户端架构 part14 of vegine)
  2. Spring 注释 @Autowired 和@Resource
  3. 浩瀚移动POS收银开单扫描解决方案PDA仓储系统,无线批发,移动批发,无线POS,无线销售APP-车销管理PDA
  4. 透透彻彻IoC(你没有理由不懂!)
  5. mybatis(一)安装
  6. Why we have to use epsg:900913 in OpenLayers
  7. 5.2:缓存中获取单例bean
  8. Asp.net中request.QueryString与request.Params的区别 【转】
  9. 深入理解C#第二版笔记
  10. ZigBee 协议规范
  11. 关于echarts的一些基本使用demo
  12. Python ORM框架之 Peewee入门
  13. pl/sql command window 初步接触
  14. 精通libGDX游戏开发-RPG实战-开发游戏的基本前提
  15. node八-核心模块、包
  16. 浅论各种调试接口(SWD、JTAG、Jlink、Ulink、STlink)的区别
  17. 如何找出单链表中的倒数第k个元素
  18. 向treeview中加载数据
  19. Lattice
  20. JAVAEmail工具错误java.lang.ClassNotFoundException: javax.activation.DataSource

热门文章

  1. CDOJ 1218 Pick The Sticks
  2. Hadoop JVM调整解决 MapReduce 作业超时问题
  3. HDU 3527 SPY
  4. 洛谷——P1547 Out of Hay
  5. poj——3118 Arbiter
  6. 【TFS 2017 CI/CD系列 - 03】-- Release篇
  7. mybatis &lt;!-- useGeneratedKeys=&quot;true&quot;把新增加的主键赋值到自己定义的keyProperty(id)中 --&gt;
  8. java quartz的使用,做时间轮询调用 CronTrigger
  9. 微信小程序 自定义组件(stepper)
  10. linux core文件设置