[BZOJ 1305] 跳舞
Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1305
Solution:
发现res是否可行具有单调性,二分答案
容易看出每次check(mid)用网络流判断,关键在于建图:
1)将每一个人拆成两个点,男孩的两个点为X1,X2,女孩为Y1,Y2
2)将相互喜欢的将X1,Y1相连,互相讨厌的将X2,Y2相连,容量为1
3)每一个X1向X2连一条容量为k的边,每一个Y2向Y1连一条容量为k的边
4)从源点向每一个X1连容量mid的边,从每一个Y1向汇点连容量为mid的边
这里建图的难点还是在拆点上,
拆点的目的在于将从该点出发的流量分类,并能对每一类进行容量限制:
EX:为了使向“讨厌的”流量不超过k,我们将Xi流向“讨厌的”节点的流量专门设一个源点(分类)
这样将 Xi1 ----> Xi2 的容量设为k即可满足这一条件(加以容量限制)
于是当遇到每个点根据不同流向的流量要加以不同限制时,
考虑将点拆成好几个,再对每个点建一个总源点(此题没有必要,只有2类)
Code:
#include <bits/stdc++.h> using namespace std; const int MAXN=+;
const int INF=<<; struct edge
{
int to,cap,rev;
};
vector<edge> G[MAXN]; char dat[MAXN][MAXN];
int n,k,S,T,level[MAXN],iter[MAXN]; void add_edge(int from,int to,int cap)
{
G[from].push_back(edge{to,cap,G[to].size()});
G[to].push_back(edge{from,,G[from].size()-});
} bool bfs()
{
memset(level,-,sizeof(level));
queue<int> que;que.push(S);level[S]=; while(!que.empty())
{
int u=que.front();que.pop();
for(int i=;i<G[u].size();i++)
{
edge v=G[u][i];
if(v.cap && level[v.to]==-)
level[v.to]=level[u]+,que.push(v.to);
}
}
return level[T]!=-;
} int dfs(int v,int f)
{
if(v==T) return f;
int ret=;
for(int& i=iter[v];i<G[v].size();i++)
{
edge &e=G[v][i];
if(e.cap && level[e.to]==level[v]+)
{
int d=dfs(e.to,min(f,e.cap));
e.cap-=d;G[e.to][e.rev].cap+=d;ret+=d;f-=d; //一定要加f-=d
if(!f) break; //这里的剪枝很重要
}
}
return ret;
} int dinic()
{
int ret=;
while(bfs())
memset(iter,,sizeof(iter)),ret+=dfs(S,INF);
return ret;
} void build(int flow)
{
for(int i=;i<MAXN;i++) G[i].clear();
for(int i=;i<=n;i++) add_edge(S,i,flow),add_edge(i,i+*n,k);
for(int i=n+;i<=*n;i++) add_edge(i,T,flow),add_edge(i+*n,i,k);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(dat[i][j]=='Y') add_edge(i,n+j,);
else add_edge(i+*n,n+j+*n,);
} int main()
{
scanf("%d%d",&n,&k);
S=;T=*n+;
for(int i=;i<=n;i++) scanf("%s",dat[i]+); int l=,r=; //从0开始二分
while(l<=r)
{
int mid=(l+r)>>;
build(mid);
if(dinic()<n*mid) r=mid-;
else l=mid+;
}
printf("%d",r);
return ;
}
Review:
关于Dinic的两种模板:
(1)找到一条路径便立即返回
(2)对于每个点枚举完所有情况后一起返回
由于Dinic能加上当前弧优化,所以(1)虽然开栈次数看上去多了,但效率绝对不比(2)差
而(2)如果不加上容量已为0时的剪枝,则要比(1)慢得多
注意:使用(2)时每次一定要f-=d
[BZOJ 1305] 跳舞的更多相关文章
- BZOJ 1305 跳舞(二分+网络流)
无法直接构造最大流来解决这个问题,因为题目要求每首舞曲都需要n对男女进行跳舞. 答案又满足单调性,这启发我们二分答案,判断是否满流验证答案. 假设舞曲数目为x时满足条件,那么每个男生和女生都需要跳x次 ...
- bzoj 1305: [CQOI2009]dance跳舞
题目链接 bzoj 1305: [CQOI2009]dance跳舞 题解 男,女生拆点A1A2,B1B2,拆成两点间分别连容量为K的边,限制与不喜欢的人跳舞的数量 A1连接源点容量为x,B1连接汇点容 ...
- BZOJ 1305: [CQOI2009]dance跳舞 二分+最大流
1305: [CQOI2009]dance跳舞 Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲 ...
- BZOJ 1305: [CQOI2009]dance跳舞( 最大流 )
云神代码很短...0 ms过的...看了代码 , 大概是贪心... orz 我不会证 数据这么小乱搞就可以了吧... ←_← 这道题网络流还是可以写的... 既然限制了最多只能和 k 个不喜欢的人da ...
- BZOJ 1305 dance跳舞 二分+最大流
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1305 题目大意: 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成 ...
- BZOJ 1305 [CQOI2009]dance跳舞(二分+网络流)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1305 [题目大意] 一次舞会有n个男孩和n个女孩. 每首曲子开始时,所有男孩和女孩恰好 ...
- BZOJ 1305 dance跳舞(最大流+二分答案)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1305 解题思路:转自:https://blog.csdn.net/u012288458/ ...
- BZOJ 1305:dance跳舞(二分+最大流)
一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲.有一些男孩女孩相互喜欢,而其他相互不喜欢(不会“单向喜欢”).每个男孩 ...
- BZOJ 1305: [CQOI2009]dance跳舞 网络最大流_二分答案_建模
Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲.有一些男孩女孩相互喜欢,而其他相互不喜欢(不会 ...
随机推荐
- [学习笔记]可持久化数据结构——数组、并查集、平衡树、Trie树
可持久化:支持查询历史版本和在历史版本上修改 可持久化数组 主席树做即可. [模板]可持久化数组(可持久化线段树/平衡树) 可持久化并查集 可持久化并查集 主席树做即可. 要按秩合并.(路径压缩每次建 ...
- 【BZOJ3887】【Usaco2015 Jan】Grass Cownoisseur Tarjan+Spfa
我们可以看出这个东西可以缩点成DAG,因为我们在所称的点里用特技的话,要么没用,要么削弱自己对点的收割能力与边的联通权,所以我们缩完点之后在图上枚举反向的变,因为我们只可能反向一条边,而且我们知道在这 ...
- Codeforces Round #506 (Div. 3) 题解
Codeforces Round #506 (Div. 3) 题目总链接:https://codeforces.com/contest/1029 A. Many Equal Substrings 题意 ...
- bzoj5091 [Lydsy1711月赛]摘苹果 概率题
[Lydsy1711月赛]摘苹果 Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 174 Solved: 135[Submit][Status][Dis ...
- Qt5 界面中文乱码问题
1.文件所在项目文件 xxx.pro 中添加: QMAKE_CXXFLAGS += -execution-charset:utf- 2.文件以 UTF-8 编码保存 3.添加 utf-8 BOM
- 7月16号day8总结
今天学习过程和小结 1.列举Linux常用命令 shutdown now Linux关机 rebot重启 mkdir mkdir -p递归创建 vi/touth filename rm -r file ...
- tomcat 配置文件中设置JAVA_HOME
Tomcat默认情况下会用系统的环境变量中找到JAVA_HOME和JRE_HOME.但是有的时候我们需要不同版本的JDK共存. 可以在${TOMCAT_HOME}/bin/setclasspath.b ...
- AngularJs学习——模拟用户登录的简单操作
效果截图:
- bzoj2002 弹飞绵羊 分块
这道题是分块的初尝试 讲给定的区间n进行分块处理 这个每次修改的复杂的只有logn 很方便 代码是学黄学长的 http://hzwer.com/3505.html 当然里面还是有一定我自己的想法在里面 ...
- RabbitMQ消息队列(一): 简单队列
1. 示例选用python的pika模块进行测试,需要预先安装pika模块: https://pypi.python.org/pypi/pika/0.10.0#downloads 上述地址下载源码,加 ...