BZOJ-1305 dance跳舞 建图+最大流+二分判定
跟随YveH的脚步又做了道网络流。。。%%%
1305: [CQOI2009]dance跳舞
Time Limit: 5 Sec Memory Limit: 162 MB
Submit: 2119 Solved: 878
[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
加强数据By dwellings and liyizhen2
这道题,网上有说可以贪心的,然而似乎被证明是错误的了,(反正我也想不出贪心策略)
说一下建图:(建图有点麻烦,多谢恒妹的查错)
每个男孩建立两个次节点,每个女孩建立两个次节点,分别处理喜欢的和不喜欢的
超级源S向所有男生主节点连边,所有女生向超级汇连边,边权为二分枚举出来的值
男生主节点和处理喜欢的男生次节点连边边权为INF,向处理不喜欢的男生连边边权为k
女生处理喜欢的次节点向主节点连边,边权INF;处理不喜欢的次节点与主节点相连边权为k
相互喜欢的男生女生的喜欢节点相连边权为1,相互不喜欢的连边,边权为1
二分答案,及超级源指向男生主节点的边权(女生主节点指向超级汇的边权)
每次二分出答案重新建图,跑一边Dinic判断是否满流,最后输出二分出边权即可。
(这道题目不错不错)
(一开始没写二分写了个枚举,结果卡常了。。。“竟然被卡常了,666啊”—by YveH)
code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int q[3000],h,t;
struct data{
int to,next,v;
}edge[1000001];
int cnt;
int head[3000]={0};
int dis[3000]={0};
int xh[51][51];
int n,k,num;
void add(int u,int v,int w)
{
cnt++;
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt;
edge[cnt].v=w;
}
void init()
{
scanf("%d%d",&n,&k);
for (int i=1; i<=n; i++)
{
char x[51];
scanf("%s",&x);
for (int j=1; j<=n; j++)
if (x[j-1]=='Y')
xh[i][j]=1;
}
}
void make(int v)
{
//男生i的主点序号为 in 则处理喜欢的次点序号为in+1,处理不喜欢的次点序号为in+2
//女生同理,接男生后面排
//超级源的序号0,超级汇为2*n*3+1
cnt=1; memset(head,0,sizeof(head));
num=1;
for (int i=1; i<=n; i++)
{
add(0,num,v);add(num,0,0);
num++;
add(num-1,num,0x7fffffff);add(num,num-1,0);
num++;
add(num-2,num,k);add(num,num-2,0);
num++;
}
for (int i=1; i<=n; i++)
{
add(num,2*n*3+1,v);add(2*n*3+1,num,0);
num++;
add(num,num-1,0x7fffffff);add(num-1,num,0);
num++;
add(num,num-2,k);add(num-2,num,0);
num++;
}
for (int i=1; i<=n; i++)
{
for (int j=1; j<=n; j++)
{
if (xh[i][j]==1)
{
add(i*3-2+1,3*n+j*3-2+1,1);
add(3*n+j*3-2+1,i*3-2+1,0);
}
else
{
add(i*3-2+2,3*n+j*3-2+2,1);
add(3*n+j*3-2+2,i*3-2+2,0);
}
}
}
}
bool bfs()
{
memset(dis,-1,sizeof(dis));
q[1]=0; dis[0]=1;
h=0; t=1;
while (h<t)
{
int j=q[++h],i=head[j];
while (i)
{
if (edge[i].v>0 && dis[edge[i].to]<0)
{
dis[edge[i].to]=dis[j]+1;
q[++t]=edge[i].to;
}
i=edge[i].next;
}
}
if (dis[num]>0)
return true;
else
return false;
}
int dfs(int loc,int low)
{
int now=0;
if (loc==num) return low;
int i=head[loc];
while (i)
{
if (edge[i].v>0 && dis[edge[i].to]==dis[loc]+1 && (now=dfs(edge[i].to,min(edge[i].v,low))))
{
edge[i].v-=now;
edge[i^1].v+=now;
return now;
}
i=edge[i].next;
}
return 0;
}
int main()
{
init();
int ans;
int flow;
int l=0,r=50;
while (l<=r)
{
int mid=(l+r)>>1;
make(mid);
flow=0;
while (bfs())
{
int now=0;
while ((now=dfs(0,0x7fffffff)))
flow+=now;
}
if (mid*n<=flow)
{l=mid+1;ans=mid;}
else
r=mid-1;
}//二分判断是否满流
printf("%d",ans);
return 0;
}
BZOJ-1305 dance跳舞 建图+最大流+二分判定的更多相关文章
- BZOJ 1305 dance跳舞 二分+最大流
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1305 题目大意: 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成 ...
- bzoj 1305 dance跳舞
最大流. 首先二分答案,问题转化为x首舞曲是否可行. 考虑建图,对每个人建立三个点,分别表示全体,喜欢和不喜欢. 源点向每个男生全体点连一条容量为x的边. 每个男生整体点向喜欢点连一条容量为正无穷的边 ...
- BZOJ 1305 dance跳舞(最大流+二分答案)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1305 解题思路:转自:https://blog.csdn.net/u012288458/ ...
- BZOJ 1305--[CQOI2009]dance跳舞(最大流)
1305: [CQOI2009]dance跳舞 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 4150 Solved: 1792[Submit][St ...
- 志愿者招募 HYSBZ - 1061(公式建图费用流)
转自神犇:https://www.cnblogs.com/jianglangcaijin/p/3799759.html 题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管. ...
- 2018.09.27 codeforces1045A. Last chance(线段树优化建图+最大流)
传送门 看完题应该都知道是网络流了吧. 但是第二种武器直接建图会gg. 因此我们用线段树优化建图. 具体操作就是,对于这m个人先建一棵线段树,父亲向儿子连容量为inf的边,最后叶子结点向对应的人连容量 ...
- 洛谷 P5331 - [SNOI2019]通信(CDQ 分治优化建图+费用流)
题面传送门 首先熟悉网络流的同学应该能一眼看出此题的建模方法: 将每个点拆成两个点 \(in_i,out_i\),连一条 \(S\to in_i\),容量为 \(1\) 费用为 \(0\) 的边 连一 ...
- 【BZOJ-1570】BlueMary的旅行 分层建图 + 最大流
1570: [JSOI2008]Blue Mary的旅行 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 388 Solved: 212[Submit ...
- BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)
题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...
随机推荐
- MySQL数据库学习笔记(二)----MySQL数据类型
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- Unity3D实现赛车的灯光效果
车灯的需求 在赛车游戏中,遇到灯光弱的环境,赛车车可以打开前车灯照亮路边及前方,那一定是非常酷! 也见过虚拟现实项目通过Unity模拟汽车车灯的效果,但是我还没有想到好的思路来实现. 我的思路 使用( ...
- NVIDIA Physix Unity3D
提升机器的3D性能 在公司用的台式机看配置不会很差,但是在处理3D方面特别地无奈!例如开个PS,3d MAX就会卡的半死,再多开一会儿就直接未响应,然后机器重启. 真无奈啊,公司暂时也不会给我换电脑或 ...
- js实现复制功能
JS 点击复制Copy 1.实现点击按钮,复制文本框中的的内容 1 <script type="text/javascript"> 2 function copyUrl ...
- RDLC系列之五 初试XAML
本章只讲解xaml部分,其余都和winform下一样 1.xaml代码 <Window x:Class="RDLC.WPF.MainWindow" xmlns="h ...
- html的解析
Web页面运行在各种各样的浏览器当中,浏览器载入.渲染页面的速度直接影响着用户体验 简单地说,页面渲染就是浏览器将html代码根据CSS定义的规则显示在浏览器窗口中的这个过程.先来大致了解一下浏览器都 ...
- [资料]Nginx做IP访问限制以及正则规则
nginx配置location总结及rewrite规则写法 Nginx Location配置总结 Nginx 禁止某个IP访问 server { listen 443; root /webroot/; ...
- 在 WinForm 中使用 Direct2D
在 C# 的 WinForm 应用中,界面的绘制使用的是 GDI+.不过在一些特别的应用中,可能需要用硬件加速来提高绘制的效率.下面就来介绍两种在 WinForm 应用中嵌入 Direct2D 的方法 ...
- SQLServer如何删除字段中的某个字符串,或者替换为空格?
sql="update Table set 字段=REPLACE ( 字段,'123' , ' ') where XXX条件"把字段中123替换为空格
- Winform调用百度地图接口
using System; using System.IO; using System.Collections.Generic; using System.ComponentModel; using ...