题目链接:【http://hihocoder.com/problemset/problem/1393】

题意:中文题意。

题解:二分图的多重匹配。主要是建图然后跑一个最带流,再判断一下就可以了。

建图:首先要保证每个学生最多选择a[i]节课,那么我们建立一个超级起点S,S->学生,流量为学生最多选的课数,然后每个学生向它喜欢的课程建立一条流量为1的边,然后又要保证每个项目的人数,每个项目向超级汇点T建立一条流量为M[i]的边,表示每节课最多上M[i]个人。然后跑最大流,判断指向终点的边是不是满载就可以了。

【http://blog.csdn.net/tramp_1/article/details/52663763】推荐博客。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = ;
const int maxm = ;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to, next, cap, flow;
Edge(int to = , int next = , int cap = , int flow = ): to(to), next(next), cap(cap), flow(flow) {}
} edge[maxm];
int head[maxn], tot;
void init()
{
memset(head, -, sizeof(head));
tot = ;
}
void addedge(int u, int v, int w, int rw = )
{
edge[tot] = Edge(v, head[u], w, );
head[u] = tot++;
edge[tot] = Edge(u, head[v], rw, );
head[v] = tot++;
}
int gap[maxn], dep[maxn], pre[maxn], cur[maxn];
int sap(int st, int ed, int nodenum)
{
memset(gap, , sizeof(gap));
memset(dep, , sizeof(dep));
memcpy(cur, head, sizeof(head));
int u = st;
pre[u] = -;
gap[] = nodenum;
int ans = ;
while(dep[st] < nodenum)
{
if(u == ed)
{
int Min = INF;
for(int i = pre[u]; i != -; i = pre[edge[i ^ ].to])
if(Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
for(int i = pre[u]; i != -; i = pre[edge[i ^ ].to])
{
edge[i].flow += Min;
edge[i ^ ].flow -= Min;
}
u = st;
ans += Min;
continue;
}
bool fg = false;
int v;
for(int i = cur[u]; i != -; i = edge[i].next)
{
v = edge[i].to;
if(edge[i].cap - edge[i].flow && dep[v] + == dep[u])
{
fg = true;
cur[u] = pre[v] = i;
break;
}
}
if(fg)
{
u = v;
continue;
}
int Min = nodenum;
for(int i = head[u]; i != -; i = edge[i].next)
if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
{
Min = dep[edge[i].to];
cur[u] = i;
}
gap[dep[u]]--;
if(!gap[dep[u]]) return ans;
dep[u] = Min + ;
gap[dep[u]]++;
if(u != st) u = edge[pre[u] ^ ].to;
}
return ans;
}
int T, n, m;
int main ()
{
scanf("%d", &T);
while(T--)
{
init();
scanf("%d%d", &n, &m);
int num = ;
for(int i = ; i <= m; i++)
{
int t;
scanf("%d", &t);
num += t;
addedge(n + i, n + m + , t);
}
for(int i = ; i <= n; i++)
{
int x, t;
scanf("%d%d", &t, &x);
addedge(, i, t);
for(int j = ; j <= x; j++)
{
scanf("%d", &t);
addedge(i, n + t, );
}
}
int flow = sap(, n + m + , n + m + );
if(flow == num)
printf("Yes\n");
else
printf("No\n");
}
return ;
}

hiho1393二分图多重匹配的更多相关文章

  1. hihoCoder 1393 网络流三·二分图多重匹配(Dinic求二分图最大多重匹配)

    #1393 : 网络流三·二分图多重匹配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小H ...

  2. 【POJ 1698】Alice's Chance(二分图多重匹配)

    http://poj.org/problem?id=1698 电影和日子匹配,电影可以匹配多个日子. 最多有maxw*7个日子. 二分图多重匹配完,检查一下是否每个电影都匹配了要求的日子那么多. #i ...

  3. 稳定的奶牛分配 && 二分图多重匹配+二分答案

    题意: 农夫约翰有N(1<=N<=1000)只奶牛,每只奶牛住在B(1<=B<=20)个奶牛棚中的一个.当然,奶牛棚的容量有限.有些奶牛对它现在住的奶牛棚很满意,有些就不太满意 ...

  4. hiho 第117周 二分图多重匹配,网络流解决

    描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含 ...

  5. 【网络流24题】No.7 试题库问题 (最大流,二分图多重匹配)

    [题意] 假设一个试题库中有 n 道试题. 每道试题都标明了所属类别. 同一道题可能有多个类别属性.现要从题库中抽取 m 道题组成试卷.并要求试卷包含指定类型的试题. 试设计一个满足要求的组卷算法. ...

  6. POJ2584 T-Shirt Gumbo【二分图多重匹配】

    题目链接: id=2584">http://poj.org/problem?id=2584 题目大意: 如今有5种型号(S.M.L.X.T)的衣服要发放给N个參赛队员.给出每一个參赛者 ...

  7. 网络流24题 第五题 - PowerOJ1740 CodeVS1905 圆桌问题 二分图多重匹配 网络最大流

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - PowerOJ1740 - 有SPJ - 推荐 题目传送门 - CodeVS1905 - 无SPJ - 0% ...

  8. [HihoCoder1393]网络流三·二分图多重匹配

    题目大意: 班级有$N$名学生,运动会有$M$项不同的比赛,第$i$项比赛每个班需要派出$m_i$名选手参加,编号为i的学生最多同时参加给定的$b_i$项比赛中的任意$a_i$项比赛.根据统计的结果, ...

  9. hdu3605 Escape 二分图多重匹配/最大流

    2012 If this is the end of the world how to do? I do not know how. But now scientists have found tha ...

随机推荐

  1. 查询PHP版本

    查询php版本: phpinfo();

  2. MongoDB之安装和基本使用(一)

    环境 ubuntu16.04 mongodb基本特点 MongoDB 是一个基于分布式 文件存储的NoSQL数据库;可以把MongoDB想象成一个大py字典. 模式自由 :可以把不同结构的文档存储在同 ...

  3. Linux进程的创建函数fork()及其fork内核实现解析【转】

    转自:http://www.cnblogs.com/zengyiwen/p/5755193.html 进程的创建之fork() Linux系统下,进程可以调用fork函数来创建新的进程.调用进程为父进 ...

  4. Ubuntu16.04安装记

    Ubuntu16.04安装记 基本信息: 华硕笔记本 Windows 10 家庭版 处理器:Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz 2.71GHz 已安装的内 ...

  5. git中如何查看一个文件的修改(更新)历史

    有些时候有些文件或文件夹被移除了, 或者更换了路径或被改名了, 想跟踪一下这个文件被修改(更新)的历史, 可以用如下命令: git log -p matser -- filename 格式是: git ...

  6. 【Learn】CSS定义

    CSS基础语法 本文用于介绍CSS相关的知识,用于记录自己的学习笔记.由于我已经熟悉了部分的HTML,所以相关的概念也不在这里进行描述了,直接写自己的一些心得感悟. 1.CSS规则 CSS是由两个主要 ...

  7. aws rds

    1.还原快照,注意设置安全组的问题:不然会导致还原后连接不上:

  8. 最全Pycharm教程(26)——Pycharm搜索导航之文件名、符号名搜索(转)

    1.准备一个工程 向你的工程中添加一个Python文件,并输入一些源码,例如: 2.转到对应文件.类.符号 Pycharm提供的一个很强力的功能就是能够根据名称跳转到任何文件.类.符号所在定义位置. ...

  9. HDU 1686 Oulipo(KMP变形求子串出现数目(可重))

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1686 题目大意:给两个字符串A,B求出A中出现了几次B(计算重复部分). 解题思路:稍微对kmp()函 ...

  10. Windows内核进程管理器解析

    Windows内核是如何实现线程挂起的?如何实现线程挂载到进程的?如何实现杀死进程和线程的? 从源码分析一下,这些操作具体在源码上是如何实现的. 进程创建.线程切换.线程跨越CPU权限级.进程挂靠.杀 ...