【网络流二十四题 圆桌聚餐】【二分图多重匹配->最大流】
来源:互联网 发布:sql图书管理系统 编辑:程序博客网 时间:2024/06/05 18:44
问题模型: 二分图多重匹配
转化模型 :最大流
我是来这里认罪的!
我没加边跑网络流!我加了个自环!我 Dinic 模板还打错了!
你们快来嘲讽一下我!我是罪人!还连累小 ly!
建图
建立二分图,每个单位为 X
集合中的顶点,每个餐桌为 Y
集合中的顶点,增设附加源 S
和汇 T
。
1、从 S
向每个 Xi
顶点连接一条容量为该单位人数的有向边。
2、从每个 Yi
顶点向 T
连接一条容量为该餐桌容量的有向边。
3、X
集合中每个顶点向 Y
集合中每个顶点连接一条容量为 1
的有向边。
求网络最大流,如果最大流量等于所有单位人数之和,则存在解,否则无解。对于每个单位,从 X
集合对应点出发的所有满流边指向的 Y
集合的顶点就是该单位人员的安排情况(一个可行解)。
–
对于一个二分图,每个顶点可以有多个匹配顶点,称这类问题为二分图多重匹配问题。X
,Y
集合之间的边容量全部是 1
,保证两个点只能匹配一次(一个餐桌上只能有一个单位的一个人),源汇的连边限制了每个点匹配的个数。求出网络最大流,如果流量等于 X
集合所有点与 S
边容量之和,那么则说明 X
集合每个点都有完备的多重匹配。
#include <bits/stdc++.h>using namespace std;const int N = 2e5 + 5, inf = 0x7fffffff;struct Edge { int next, to, c; }e[N << 1];int m, n, s, t;int cnt = 1;int head[N], cur[N];void add(int u, int v, int c) { e[++ cnt].to = v; e[cnt].c = c; e[cnt].next = head[u]; head[u] = cnt; e[++ cnt].to = u; e[cnt].c = 0; e[cnt].next = head[v]; head[v] = cnt;}int dep[N];bool bfs(int x) { queue<int> q; memset(dep, 0, sizeof(dep)); dep[x] = 1; q.push(x); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = head[u]; i; i = e[i].next) { int v = e[i].to; if (!dep[v] && e[i].c) { dep[v] = dep[u] + 1; q.push(v); } } } if (!dep[t]) return 0; return 1;}int dfs(int u, int flow) { if (u == t) return flow; for (int &i = cur[u]; i; i = e[i].next) { int v = e[i].to; if (dep[v] == dep[u] + 1 && e[i].c) { int nowflow = dfs(v, min(flow, e[i].c)); if (nowflow > 0) { e[i].c -= nowflow; e[i ^ 1].c += nowflow; return nowflow; } } } return 0;}int Dinic() { int res = 0; while(bfs(s)) { for (int i = s; i <= t; i ++) cur[i] = head[i]; while(int d = dfs(s, inf)) res += d; } return res;}int main() { int sum = 0; scanf("%d%d", &m, &n); s = 0, t = m + n + 1; for (int i = 1; i <= m; i ++) for (int j = 1; j <= n; j ++) add(i, j + m, 1); for (int i = 1; i <= m; i ++) { int r; scanf("%d", &r); sum += r; add(s, i, r); } for (int i = 1; i <= n; i ++) { int c; scanf("%d", &c); add(m + i, t, c); } int ans = Dinic(); if (ans != sum) printf("0\n"); else { printf("1\n"); for (int u = 1; u <= m; u ++) { for (int i = head[u]; i; i = e[i].next) { int v = e[i].to; if (!e[i].c && v != s) printf("%d ", v - m); } printf("\n"); } } return 0;}
阅读全文
0 0
- 【网络流二十四题 圆桌聚餐】【二分图多重匹配->最大流】
- 【网络流二十四题 试题库问题】【二分图多重匹配->最大流】
- 圆桌问题【二分图多重匹配】网络流24题
- 【loj】#6004. 「网络流 24 题」圆桌聚餐(二分图匹配)
- 【网络流24题】圆桌聚餐(二分图)
- [网络流24题] 圆桌聚餐 最大流/路径输出
- [网络流24题] 05 圆桌聚餐(最大流判满流)
- 线性规划与网络流24题の5 圆桌问题(二分图多重匹配)
- [网络流24题] 圆桌聚餐
- [网络流24题]圆桌聚餐
- 网络流24题 05圆桌聚餐
- cogs729. [网络流24题] 圆桌聚餐
- 网络流24题 圆桌聚餐
- loj #6004. 「网络流 24 题」圆桌聚餐(最大流)
- loj6004「网络流 24 题」圆桌聚餐(最大流)
- 二分图的多重最大匹配——网络流
- COGS 729 [网络流24题] 圆桌聚餐
- Cogs 729. [网络流24题] 圆桌聚餐
- ngrok 外网搭建
- python pandas 位置索引
- eclipse 配置Tomcat
- Android中内容提供者ContentProvider的详解
- 内存数据库优劣势有那些?
- 【网络流二十四题 圆桌聚餐】【二分图多重匹配->最大流】
- Android 子view超出父View效果
- python基础之正则表达式和re模块
- JavaWeb Session过期验证
- 安卓开发中,小知识点:onConfigurationChanged方法未调用,onMeasure的使用
- 镜映自我与群体结构
- Capstone训练营5
- ConfigHelper.cs
- 【转】苹果开发者账号申请(2017最新版)