ZOJ 3642 多重匹配 离散化.cpp
2012-09-21 20:28
155 查看
[b]题意:[/b]
已知一些小孩所拥有的信息和他最多共享信息量和最少共享信息量 问其中某一个小孩最多得到的信息量
给出n表示有n个小孩
接下来n行有 a b c a1 a2 a3 a4 ... ai 表示该小孩有信息a条 最少共享 b 条 最多共享 c 条 其中a1 a2 a3~ai为小孩拥有信息id号
给出一个m 问的是小孩m最多得到的信息量
[b]思路:[/b]
鉴于这道题中信息id号从 0 ~ 200 但是每个小孩最初最多知道10条信息..
所以为了防止遍历的时候太浪费时间 应该把题目id号变成连续的..
然后可以用多重匹配或者最大流来做..
[b]Tips:[/b]
多重匹配的建图方法:
以信息为 集合X 孩子为 集合Y
然后 limit 为 Y 集合的最大容量 即孩子的最大共享量 但是孩子 m 的容量为INF
最大流的建图方法:
一个超级源点..连接孩子 除了第m个孩子之外..
别的孩子都连线..容量为最大分享量..而第m个孩子的容量为INF 表示可以接受无穷多的信息
然后每个孩子和对应的信息连线 容量为1
每个信息又与超级汇点连线 容量为1
求超级源点到超级汇点的最大流既是答案
[b]Code:[/b]
多重匹配
[b]题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4810[/b]
已知一些小孩所拥有的信息和他最多共享信息量和最少共享信息量 问其中某一个小孩最多得到的信息量
给出n表示有n个小孩
接下来n行有 a b c a1 a2 a3 a4 ... ai 表示该小孩有信息a条 最少共享 b 条 最多共享 c 条 其中a1 a2 a3~ai为小孩拥有信息id号
给出一个m 问的是小孩m最多得到的信息量
[b]思路:[/b]
鉴于这道题中信息id号从 0 ~ 200 但是每个小孩最初最多知道10条信息..
所以为了防止遍历的时候太浪费时间 应该把题目id号变成连续的..
然后可以用多重匹配或者最大流来做..
[b]Tips:[/b]
多重匹配的建图方法:
以信息为 集合X 孩子为 集合Y
然后 limit 为 Y 集合的最大容量 即孩子的最大共享量 但是孩子 m 的容量为INF
最大流的建图方法:
一个超级源点..连接孩子 除了第m个孩子之外..
别的孩子都连线..容量为最大分享量..而第m个孩子的容量为INF 表示可以接受无穷多的信息
然后每个孩子和对应的信息连线 容量为1
每个信息又与超级汇点连线 容量为1
求超级源点到超级汇点的最大流既是答案
[b]Code:[/b]
多重匹配
#include <stdio.h> #include <cstring> #include <algorithm> using namespace std; #define clr(x) memset(x, 0, sizeof(x)) const int INF = 0x1f1f1f1f; bool G[410][210]; int limit[410]; bool vis[410]; int v1, v2, sum; int v[410]; int vv[210][410]; int num[1000010]; bool find(int u) { int i, j, k; for(i = 0; i < v2; ++i) { if(G[u][i] && !vis[i]) { vis[i] = true; if(v[i] < limit[i]) { vv[i][v[i]++] = u; return true; } for(j = 0; j < v[i]; ++j) { if(find(vv[i][j])) { vv[i][j] = u; return true; } } } } return false; } void solve() { clr(vis); sum = 0; for(int i = 1; i <= v1; ++i) { clr(vis); if(find(i)) { sum++; } } } int main() { int i, j, k; int n, m, tmp, tt; while(scanf("%d", &n) != EOF) { clr(G), clr(num); tt = 1; for(i = 0; i < n; ++i) { scanf("%d%*d%d", &m, &limit[i]); while(m--) { scanf("%d", &tmp); if(num[tmp] == 0) num[tmp] = tt++; G[num[tmp]][i] = true; } } v1 = tt-1; v2 = n; scanf("%d", &m); limit[m-1] = INF; solve(); printf("%d\n", sum); } return 0; }
[b]题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4810[/b]
相关文章推荐
- ZOJ 3642 Just Another Information Sharing Problem【二分图多重匹配】
- HDOJ 3642 Get The Treasury(扫描线 + 线段树 + 离散化 立方体的并)
- ZOJ1654 Place the Robots(二分图最大匹配)
- 浙大 zoj 1654 Place the Robots (二分匹配 + 关于x,y轴的构造边)
- zoj 2301 || hdu 1199 Color the Ball 线段树 离散化
- ZOJ 1364 Machine Schedule (POJ 1325) (最小点覆盖数==最大匹配数)
- ZOJ - 1654 Place the Robots (构图 最大匹配)
- ZOJ 3156 Taxi (二分匹配+二分查找)
- ZOJ 3642
- 【ZOJ 3642】 Just Another Information Sharing Problem
- 第8周项目5 - 计数的模式匹配.cpp
- ZOJ 1516 Uncle Tom's Inherited Land (二分图最大匹配)
- ZOJ 3299 线段树 离散化
- ZOJ 1654 Place the Robots(最大匹配)
- zoj_1654_最大匹配
- ZOJ 1516--Uncle Tom's Inherited Land【二分图 && 求最大匹配数 && 经典建图】
- ZOJ 2010 Equipment Box(POJ 1380)(暴力离散化)
- ZOJ 1016 Parencodings (括号匹配) 思路
- ZOJ 3988 && 2017CCPC秦皇岛 H:Prime Set(二分匹配)
- ZOJ 3016 Cut(离散化+最小生成树)