#1393 : 网络流三·二分图多重匹配

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来。

小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上。

已知小Hi和小Ho所在的班级一共有N名学生(包含小Hi和小Ho),编号依次为1..N。

运动会一共有M项不同的比赛,编号为1..M。第i项比赛每个班需要派出m[i]名选手参加。

根据小Hi和小Ho的统计,编号为i的学生表示最多同时参加a[i]项比赛,并且给出他所擅长的b[i]项比赛的编号。

小Hi和小Ho希望将每个学生都安排到他所擅长的比赛项目,以增加夺冠的可能性。同时又要考虑满足每项比赛对人数的要求,当然给一个学生安排的比赛项目也不能超过他愿意参加的比赛项目数量。

根据统计的结果,小Hi和小Ho想知道能否有一个合适的安排,同时满足这些条件。

提示:二分图多重匹配

输入

第1行:1个整数T,表示一共有T(2≤T≤5)组数据,每组数据按如下格式给出:

第1行:2个正整数N,M。1≤N≤100,1≤M≤100。

第2行:M个整数,第i个数表示第i个项目需要的选手数量m[i]。1≤m[i]≤N。

第3..N+2行:若干整数,第i+2行表示编号为i的学生的信息。先是a[i],b[i],接下来b[i]个整数,表示其所擅长的b[i]个项目。1≤a[i]≤M

输出

第1..T行:第i行表示第i组数据能否满足要求,若能够输出"Yes",否则输出"No"。

样例输入
2
4 3
1 2 2
1 2 1 2
2 2 1 3
1 1 2
1 2 2 3
4 3
2 2 2
1 2 1 2
2 2 1 3
1 1 2
1 2 2 3
样例输出
Yes
No

题目链接:hihoCoder 1393

要用网络流做二分图的多重匹配就要知道二分匹配的边的作用,至少先搞懂普通二分匹配是怎么回事

先回想一下二分图的普通最大匹配是如何建图的:源点到$Xi$的容量边其实是用来表示$Xi$最多可以匹配多少个人;从$Xi$到$Yi$的容量边表示$Xi$是否能与$Yi$匹配;从$Yi$到汇点的容量边表示Yi最多可以被多少个人匹配。显然普通二分图以上容量均为1,那么参照以上的原理,多重匹配就是把最左和最右改一下即可,中间的为什么不用改呢?一个人对于一个项目的作用只有1,不可能达到两个人的效果,因此容量限制还是只有1,话说Dinic比朴素Ford_Fulkerson快了很多……可能是FF写的搓吧(dinic也没好看到哪里去)

最近要期末考了,抓紧时间复习(预习- -|||),基本就不刷题了颓废一下,考完再刷……

代码:

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 210;
const int M = 10200;
struct edge
{
int to, nxt;
int cap;
};
edge E[M << 1];
int head[N], tot;
int d[N]; void init()
{
CLR(head, -1);
tot = 0;
}
inline void add(int s, int t, int cap)
{
E[tot].to = t;
E[tot].cap = cap;
E[tot].nxt = head[s];
head[s] = tot++; E[tot].to = s;
E[tot].cap = 0;
E[tot].nxt = head[t];
head[t] = tot++;
}
int bfs(int s, int t)
{
CLR(d, INF);
d[s] = 0;
queue<int>Q;
Q.push(s);
while (!Q.empty())
{
int now = Q.front();
Q.pop();
for (int i = head[now]; ~i; i = E[i].nxt)
{
int v = E[i].to;
if (d[v] == INF && E[i].cap > 0)
{
d[v] = d[now] + 1;
if (v == t)
return 1;
Q.push(v);
}
}
}
return d[t] != INF;
}
int dfs(int s, int t, int f)
{
if (s == t || !f)
return f;
int ret = 0;
for (int i = head[s]; ~i; i = E[i].nxt)
{
int v = E[i].to;
if (d[v] == d[s] + 1 && E[i].cap > 0)
{
int dx = dfs(v, t, min(f, E[i].cap));
if (dx > 0)
{
E[i].cap -= dx;
E[i ^ 1].cap += dx;
ret += dx;
f -= dx;
if (!f)
break;
}
}
}
if (!ret)
d[s] = -1;
return ret;
}
int dinic(int s, int t)
{
int ret = 0;
while (bfs(s, t))
ret += dfs(s, t, INF);
return ret;
}
int main(void)
{
int n, m, i, d, k, a, b;
int tcase;
scanf("%d", &tcase);
while (tcase--)
{
init();
int sum = 0;
scanf("%d%d", &n, &m);
int S = 0, T = n + m + 1;
for (i = 1; i <= m; ++i)
{
int ned;
scanf("%d", &ned);
sum += ned;
add(n + i, T, ned);
}
for (i = 1; i <= n; ++i)
{
scanf("%d%d", &a, &b);
add(S, i, a);
while (b--)
{
scanf("%d", &k);
add(i, n + k, 1);
}
}
puts(dinic(S, T) == sum ? "Yes" : "No");
}
return 0;
}

hihoCoder 1393 网络流三·二分图多重匹配(Dinic求二分图最大多重匹配)的更多相关文章

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

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

  2. 洛谷 P3386 【模板】二分图匹配 Dinic版

    题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 ...

  3. 二分图匹配之KM求二分图最佳匹配算法

    参考网址:http://blog.163.com/suntroop@yeah/blog/static/17012103120115185927194/ 对于具有二部划分( V1, V2 )的加权完全二 ...

  4. CJOJ 1494 【网络流24题】 搭配飞行员(二分图最大匹配)

    CJOJ 1494 [网络流24题] 搭配飞行员(二分图最大匹配) Description 飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾 ...

  5. HDU 1533:Going Home(KM算法求二分图最小权匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 Going Home Problem Description   On a grid map there ...

  6. 网络流 最大流 Drainage Ditches Dinic

    hdu 1532 题目大意: 就是由于下大雨的时候约翰的农场就会被雨水给淹没,无奈下约翰不得不修建水沟,而且是网络水沟,并且聪明的约翰还控制了水的流速,本题就是让你求出最大流速,无疑要运用到求最大流了 ...

  7. HDU 1045 - Fire Net - [DFS][二分图最大匹配][匈牙利算法模板][最大流求二分图最大匹配]

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1045 Time Limit: 2000/1000 MS (Java/Others) Mem ...

  8. POJ-2195 Going Home---KM算法求最小权值匹配(存负边)

    题目链接: https://vjudge.net/problem/POJ-2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致.man每移动一格 ...

  9. The Accomodation of Students(判断二分图以及求二分图最大匹配)

    The Accomodation of Students Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d &a ...

随机推荐

  1. T-SQL备忘-表连接更新

    1.update a inner join b on a.id=b.id set a.name=b.name where ...   2.update table1 set a.name = b.na ...

  2. Java 内部类

    1.成员内部类 成员内部类,就是作为外部类的成员,可以直接使用外部类的所有成员和方法,即使是private的.同时外部类要访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取. 2.局部内部类 ...

  3. 字符串专题:map POJ 1002

    第一次用到是在‘校内赛总结’扫地那道题里面,大同小异 map<string,int>str 可以专用做做字符串的匹配之类的处理 string donser; str [donser]++ ...

  4. Find All Numbers Disappeared in an Array

    Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ot ...

  5. testng 教程

    Testng 简介: Testng是一套开源测试框架,是从Junit继承而来,testng意为test next generation,主要有以下特性: annotations  注释,如 @test ...

  6. webservice发布服务:CXF及客户端调用

    2.CXF:(与spring整合) CXF相对来说操作没有AXIS繁琐 1.导入spring的jar包和cxf的jar包 2.在spring的核心配置文件中配置发布的接口类 <?xml vers ...

  7. Revit 自定义RibbonPanel到Revit中

    项目下找到TheApplication.cs,更改内容: class TheApplication : IExternalApplication    {        public Result O ...

  8. Pyqt adb 获取Android手机屏幕

    adb的全称为Android Debug Bridge,就是起到调试桥的作用.adb的工作方式比较特殊,采用监听Socket TCP 5554等端口的方式让IDE和Qemu通讯,默认情况下adb会da ...

  9. Pyqt 国际化多语言支持

    国际化是指在代码设计上加入能方便的移植到其他国家和地区的特性, 给Pyqt 添加国际化支持需要五步 一.编写GUI.py 在要被翻译的text上用tr方法括起来 # -*- coding: utf-8 ...

  10. MyBatis学习(二)

    mybatis开发dao的方法 作用范围 SqlSessionFactoryBuilder是以工具类方式来使用,需要创建sqlSessionFactory就new一个SqlSessionFactory ...