P1682 过家家

题目描述

有2n个小学生来玩过家家游戏,其中有n个男生,编号为1到n,另外n个女生,编号也是1到n.每一个女生可以先选择一个和她不吵嘴的男生来玩,除此之外,如果编号为X的女生的朋友(也是女生,且编号为Y)不和编号为Z的男生吵嘴,那么X也可以选择Z.此外,朋友关系是可以传递的,比如a和b是朋友,b和c是朋友,那么我们可以认为a和c也是朋友.

当每一位女生都选择了玩伴,那么他们会开始新一轮游戏.在每一轮后,每个女生都会开始去找一个新的男生做玩伴(以前没选过).而且每一个女生最多能强制k个男生接受,无论他们以前是否吵嘴.

现在你的任务就是确定这2n个小学生最多能玩几轮游戏.

输入输出格式

输入格式:

第一行有4个整数n,m,k,f(3<=n<=250,0<m<n*n,0<=f<n).

n表示有2n个小学生,其中n个男生n个女生.

接下来m行,每行包含2个数字a,b表示编号为a的女生和编号为b的男生从没吵嘴过.

再接下来f行,每行包含2个数字c,d表示编号为c的女生和编号为d的女生是朋友.

输出格式:

对于每组数据,输出一个整数,表示2n个小学生最多能玩几轮.


这一题和P3153 [CQOI2009]跳舞几乎是一模一样,那篇题解可以看这里,建图 + 最大流 + 二分即可得到答案,这里不在赘述,写这篇题解是要解决题目中连通性的问题

题目中有提到过,朋友关系是可以传递的,比如a和b是朋友,b和c是朋友,那么我们可以认为a和c也是朋友,据此我们有两个思路:

1.并查集

2.Floyd

并查集是否可行

虽然我很擅长并查集,但是很可惜,并查集的做法在这题并不是特别适用:理由如下:

并查集的最大用处是,利用父亲这一概念很方便的判断两元素是否处于同一集合,但通过某一节点,我们不能很快确定其他节点是否与他在一集合内,唯一想到的方法是遍历所有节点,一一判断是否属于同一集合,比较麻烦,故不适用并查集。

Floyd是否可行

Floyd算法可以判断图的联通性,伪代码大概如下:

for(所有节点(作为中间点)){
for(所有节点(作为起点)){
for(所有节点(作为终点)){
if(起点与中间点联通 && 中间点与终点联通)
起点与终点联通
}
}
}

这就是传递闭包,能适用与这题,理由如下:

利用传递闭包,我们在处理完关系之后可以得到一个二维数组,可以很容易的判断两点是否联通

所以我们使用Floyd传递闭包,解决关系问题,不过要对上述伪代码做适当修改:(男孩B和女孩A玩 && 女孩A和女孩C是朋友)---> 男孩和女孩C玩

所以我们得到代码:

void Floyd(){
for(int k = num + 1;k <= 2 * num;k++){//所有女孩
for(int i = 1;i <= num;i++){//所有男孩
for(int j = num + 1;j <= 2 * num;j++){//所有女孩
dance[i][j] |= dance[i][k] && dance[k][j];//男孩选女孩(建图是也是先男孩再连女孩)
}
}
}
} //主函数部分
for(int i = 1;i <= nr;i++){
u = RD();v = RD();
dance[v][u + num] = 1;//女孩编号 + num
}
for(int i = 1;i <= nf;i++){
u = RD();v = RD();
dance[u + num][v + num] = dance[v + num][u + num] = 1;
}
Floyd();

最后二分多次建图跑最大流验证答案即可

Code

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int RD(){
int out = 0,flag = 1;char c = getchar();
while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
return flag * out;
}
const int maxn = 100019,INF = 1e9;
int num,k,nr,nf,nume = 1;
int dance[190][190];
int frind[190][190];
int s,t,maxflow;
int head[maxn << 2];
struct Node{
int v,dis,nxt;
}E[maxn << 3];
void add(int u,int v,int dis){
E[++nume].nxt = head[u];
E[nume].v = v;
E[nume].dis = dis;
head[u] = nume;
}
int d[maxn];
bool bfs(){
queue<int>Q;
memset(d,0,sizeof(d));
d[s] = 1;
Q.push(s);
while(!Q.empty()){
int u = Q.front();Q.pop();
for(int i = head[u];i;i = E[i].nxt){
int v = E[i].v;
if(E[i].dis && !d[v]){
d[v] = d[u] + 1;
if(v == t)return 1;
Q.push(v);
}
}
}
return 0;
}
int Dinic(int u,int flow){
if(u == t)return flow;
int rest = flow,k;
for(int i = head[u];i;i = E[i].nxt){
int v = E[i].v;
if(d[v] == d[u] + 1 && rest && E[i].dis){
k = Dinic(v,min(rest,E[i].dis));
if(!k)d[v] = 0;
E[i].dis -= k;
E[i ^ 1].dis += k;
rest -= k;
}
}
return flow - rest;
}
void build(int a){
memset(head,0,sizeof(head));
nume = 1;
for(int i = 1;i <= num;i++){
add(s,i,a);
add(i,s,0);//源点到每个♂
add(i + num,i + 2 * num,k);
add(i + 2 * num,i + num,0);//♀分两部
add(i + 2 * num,t,a);
add(t,i + 2 * num,0);//女到汇点
}
for(int i = 1;i <= num;i++){
for(int j = num + 1;j <= 2 * num;j++){
if(dance[i][j]){
add(i,j + num,1);
add(j + num,i,0);
}
else{
add(i,j,1);
add(j,i,0);
}
}
}
}
bool check(int mid){
build(mid);
maxflow = 0;
int flow = 0;
while(bfs())while(flow = Dinic(s,INF))maxflow += flow;
if(maxflow == mid * num)return 1;
return 0;
}
int search(int l,int r){
int ans;
while(l <= r){
int mid = l + r >> 1;
if(check(mid))l = mid + 1,ans = mid;
else r = mid - 1;
}
return ans;
}
void Floyd(){
for(int k = num + 1;k <= 2 * num;k++){
for(int i = 1;i <= num;i++){
for(int j = num + 1;j <= 2 * num;j++){
dance[i][j] |= dance[i][k] && dance[k][j];
}
}
}
}
int main(){
num = RD();nr = RD();k = RD();nf = RD();
s = num * 4 + 19;t = s + 1;
int u,v;
for(int i = 1;i <= nr;i++){
u = RD();v = RD();
dance[v][u + num] = 1;
}
for(int i = 1;i <= nf;i++){
u = RD();v = RD();
dance[u + num][v + num] = dance[v + num][u + num] = 1;
}
Floyd();
printf("%d\n",search(0,num + k));
return 0;
}

题解 P1682 【过家家】的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. 2.hive里的增删改查

    1.hive的增删改查 查询数据库 hive> show databases; OK default Time taken: 0.254 seconds, Fetched: 1 row(s) h ...

  2. 2017软工第十周个人PSP

    11.17--11.23本周例行报告 1.PSP(personal software process )个人软件过程. C(类别) C(内容) ST(开始时间) ET(结束时间) INT(间隔时间) ...

  3. UML设计(团队作业6)

    决胜 Poker 一.团队成员 学号 姓名 211606392 郑俊瑜 (队长) 211606327 冉繁盛 211606323 刘世华 211606386 姚皓钰 211606358 陈卓楠 211 ...

  4. HDU 5501 The Highest Mark

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5501 The Highest Mark  Accepts: 32  Submissions: 193 ...

  5. lilntcode-508-摆动排序

    508-摆动排序 给你一个没有排序的数组,请将原数组就地重新排列满足如下性质 nums[0] <= nums[1] >= nums[2] <= nums[3].... 注意事项 请就 ...

  6. 第二章 script元素

    <script>元素  async:可选.表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本.只对外部脚本文件有效.  charset:可选.表示通过 ...

  7. IT行业大学生就业分析报告感想

    现如今的高校毕业生每年都在增长,就业压力只增不减,人才市场挤满了人 学生们普遍的表现出就业难的情况,并且适合自己的工作也难找 从报告中也容易看出IT行业很吸引人,也是人数最多的,因此机会也就变少了 在 ...

  8. PHP Mailer 发送邮件

    <?php /* 下载网址 https://github.com/PHPMailer/PHPMailer 打开下载的压缩包文件目录 将 PHPMailer-master 下的 src 文件夹复制 ...

  9. 可以从Jar外部加载JDBC.properties的Spring-mybatis配置文件

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  10. Mybatis 点点滴滴

    相比 Hibernate ,Mybatis 实在是学习门槛低多了. 1 . 类属性和表字段的自动对应 当向数据库中插入一行数据时,<insert>标签中的占位符#{}中的占位符的值写 mo ...