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. PKI(Public Key Infrastucture)介绍

    PKI(Public Key Infrastucture)介绍 根据Wikipedia PKI词条整理. PKI(Public Key Infrastucture)是一系列的规则.策略以及过程,可以用 ...

  2. ES6的新特性(17)——Generator 函数的异步应用

    Generator 函数的异步应用 异步编程对 JavaScript 语言太重要.Javascript 语言的执行环境是“单线程”的,如果没有异步编程,根本没法用,非卡死不可.本章主要介绍 Gener ...

  3. 软件工程 speedsnail 第二次冲刺10

    20150527 完成任务:蜗牛碰到线后速度方向的调整:已经基本实现多方向的反射: 遇到问题: 问题1 反射角的问题 解决1 利用tan()三角函数 明日任务: 大总结.找到新问题.布置下一次冲刺方案

  4. Transparent Flow Migration for NFV

    Transparent Flow Migration for NFV 摘要 因为SDN提供的灵活性,NF之间存在着流量的迁入和迁出问题.而且NF也要根据相关的状态信息处理数据包,所以流量迁移必须满足以 ...

  5. 【数位dp】Enigma

    http://codeforces.com/gym/101889 E 与一般数位dp不同,保存的是能否满足条件,而非记录方案数 代码: #include <iostream> #inclu ...

  6. C++ Primer Plus学习:第七章

    C++入门第七章:函数-C++的编程模块 函数的基本知识 要使用C++函数,必须完成如下工作: 提供函数定义 提供函数原型 调用函数 库函数是已经定义和编译好的函数,可使用标准库头文件提供原型. 定义 ...

  7. Qt容器类汇总说明

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt容器类汇总说明     本文地址:http://techieliang.com/2017/ ...

  8. Spring配置声明

    <...     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xmlns:p="htt ...

  9. 【c】线性表

    数据对象集:线性表是N(>=0)个元素构成的有序序列,a1,a2,a3.....a(N-1),aN,a(N+1) 线性表上的基本操作有: ⑴ 线性表初始化:Init_List(L)初始条件:表L ...

  10. html5兼容

    You can download the latest version of HTML5shiv from github or reference the CDN version at https:/ ...