这个题是很难往网络流上面构思的。。。

从s向每个物品增加容量为Bob拥有数的弧,然后从每个物品向t增加容量为1的弧(代表种类个数)。这时候跑最大流的话,得到的肯定是Bob拥有的初始种类数。那么交换后的最大数呢?

对于Bob以外的小伙伴,如果i拥有j物品超过1个(交换后他自己至少保留一个),从人节点i向物品节点j增加容量为num-1的弧,表示他能输出多少物品,而如果i没有j物品,那么从物品节点j向人节点i增加容量为1的弧(他最多接受1单位的物品)。然后跑最大流得到的就是答案了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<fstream>
#include<sstream>
#include<bitset>
#include<vector>
#include<string>
#include<cstdio>
#include<cmath>
#include<stack>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define FF(i, a, b) for(int i=a; i<b; i++)
#define FD(i, a, b) for(int i=a; i>=b; i--)
#define REP(i, n) for(int i=0; i<n; i++)
#define CLR(a, b) memset(a, b, sizeof(a))
#define debug puts("**debug**")
#define LL long long
#define PB push_back
using namespace std; const int maxn = 300;
const int INF = 1e9; int n, m, s, t, num[11][30];
int d[maxn], cur[maxn];
bool vis[maxn]; struct Edge
{
int from, to, cap, flow;
};
vector<Edge> edges;
vector<int> G[maxn]; void init()
{
s = 0, t = n + m + 1; CLR(num, 0);
REP(i, t+1) G[i].clear(); edges.clear();
} void add(int from, int to, int cap)
{
edges.PB((Edge){from, to, cap, 0});
edges.PB((Edge){to, from, 0, 0});
int nc = edges.size();
G[from].PB(nc-2); G[to].PB(nc-1);
} bool bfs()
{
CLR(vis, 0);
queue<int> q; q.push(s);
d[s] = 0, vis[s] = 1;
while(!q.empty())
{
int x = q.front(); q.pop();
int nc = G[x].size();
REP(i, nc)
{
Edge e = edges[G[x][i]];
if(!vis[e.to] && e.cap > e.flow)
{
vis[e.to] = 1;
d[e.to] = d[x] + 1;
q.push(e.to);
}
}
}
return vis[t];
} int dfs(int x, int a)
{
if(x == t || a == 0) return a;
int flow = 0, f, nc = G[x].size();
for(int& i = cur[x]; i<nc; i++)
{
Edge& e = edges[G[x][i]];
if(d[x] + 1 == d[e.to] && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0)
{
e.flow += f;
edges[G[x][i]^1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
} int max_flow()
{
int flow = 0;
while(bfs())
{
CLR(cur, 0);
flow += dfs(s, INF);
}
return flow;
} int main()
{
int T; scanf("%d", &T);
FF(kase, 1, T+1)
{
scanf("%d%d", &n, &m);
init();
int x;
REP(i, n)
{
scanf("%d", &num[i][0]);
while(num[i][0]--)
{
scanf("%d", &x);
num[i][x]++;
}
}
FF(i, 1, m+1)
{
if(num[0][i]) add(s, i+n, num[0][i]);
add(i+n, t, 1);
}
FF(i, 1, n)
{
FF(j, 1, m+1)
{
if(num[i][j] > 1) add(i, j+n, num[i][j] - 1);
if(num[i][j] == 0) add(j+n, i, 1);
}
}
printf("Case #%d: %d\n", kase, max_flow());
}
return 0;
}

UVA 10779 Collectors Problem(最大流)的更多相关文章

  1. uva 10779 Collectors Problem 网络流

    链接 一共有n个人, m种收藏品, 每个人拥有的收藏品的种类和个数都是不相同的. 假设2-n这些人都只和1互相交换, 比例是1:1, 并且, 2-n这些人, 只换自己现在没有的, 如果他现在有第二种, ...

  2. AC日记——Collectors Problem uva 10779

    UVA - 10779 思路: 最大流: s向所有的贴纸的种类连边,流量为Bob拥有的数量: 然后,Bob的朋友如果没有这种贴纸,则这种贴纸向bob的朋友连边,容量1: 如果bob的朋友的贴纸很多大于 ...

  3. UVA 10779 (最大流)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33631 题目大意:Bob有一些贴纸,他可以和别人交换,他可以把自己 ...

  4. uva 11991 - Easy Problem from Rujia Liu?(STL)

    option=com_onlinejudge&Itemid=8&page=show_problem&problem=3142" target="_blank ...

  5. CJOJ 2485 UVa 11991 生日礼物 / UVa 11991 Easy Problem from Rujia Liu?

    CJOJ 2485 UVa 11991 生日礼物 / UVa 11991 Easy Problem from Rujia Liu? Description (原题来自刘汝佳<训练指南>Pa ...

  6. UVa10779 Collectors Problem(最大流)

    很容易想到源点向所类型有贴纸连边,容量为Bob一开始有的数量:然后贴纸向汇点连边,容量为1. 接下来就是交换部分的连边了.注意交换一次一次进行,每次只能交换一张. 交换,是对于两种贴纸而言,仅会发生在 ...

  7. Risk UVA - 12264 拆点法+最大流+二分 最少流量的节点流量尽量多。

    /** 题目:Risk UVA - 12264 链接:https://vjudge.net/problem/UVA-12264 题意:给n个点的无权无向图(n<=100),每个点有一个非负数ai ...

  8. UVA 820 --- POJ 1273 最大流

    找了好久这两个的区别...UVA820 WA了 好多次.不过以后就做模板了,可以求任意两点之间的最大流. UVA 是无向图,因此可能有重边,POJ 1273是有向图,而且是单源点求最大流,因此改模板的 ...

  9. UVa 11991:Easy Problem from Rujia Liu?(STL练习,map+vector)

    Easy Problem from Rujia Liu? Though Rujia Liu usually sets hard problems for contests (for example, ...

随机推荐

  1. std::advance 给迭代器增加指定偏移量

    template <class InputIterator, class Distance> void advance (InputIterator& it, Distance n ...

  2. Random Integer Generator

    先占坑.以后再修改 昨天遇到一道题, Given int Rand(1) =  0或者 1- uniformly distributed,   write a function to implemen ...

  3. 图模型的统计推断 inference in graphical models(马尔科夫链的推断)

    有关因子图(factor graphs)以及其在sum product 算法,max-algorithm中的应用,将在一下篇博客中分享. 谢谢您的关注,欢迎提出意见问题.

  4. 我的JAVA基础学习史1

    又开始学习了..很是兴奋呢~~~~ 本来是想学安卓的,但是安卓的视频课程中,第一阶段是环境,第二阶段是JAVA基础(讲课的这个老师真是在念课本,但是实在没有办法,没找到更好.更完整的资料了). 虽然以 ...

  5. 摄像头(1)拍照的主要API,权限和特性,判断有没有摄像头的方法

    支持 Android SDK支持操作Android设备内置的照相机.从Android2.3开始,支持操作多个摄像头(主要指前置摄像头和后置照相机).通过照相机可以拍照和录像. 注意事项 是否支持照相机 ...

  6. C语言中指针数组和数组指针的区别

    指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身决定.它是“储存指针的数组”的简称. 数组指针:首先它是一个指针,它指向一个数组.在32 位系统下永远是占4 个字节,至于它指 ...

  7. centos 如何用 rsyslog 搭建本地日志服务

    一.问题背景 最近项目遇到一个问题,服务器响应很慢,team中的两个有经验的工程师找了一台服务器分析了一下,发现问题出在磁盘写入过于频繁.这里大概介绍一下背景,我们的服务器上面主要是跑各种PHP接口, ...

  8. sencha touch2 动画问题

    最近在review一个项目的代码, 发现返回操作比较乱,很多"从哪里来,到哪里去的操作"被写的一塌糊涂; 按照ios系统的进场出场动画(人家的体验还是很好的,必须借鉴)为标准,使用 ...

  9. UVa 1642 (综合) Magical GCD

    题意: 给出一个数列,求一个连续的子序列,使得MGCD(i, j) =  该子序列的长度(j-i+1) × 子序列的gcd 最大,并输出这个最大值. 分析: 感觉可能要用优先队列,但貌似也用不上. 但 ...

  10. Zend Framework XML外部实体和安全绕过漏洞

    漏洞版本: Zend Framework 1.x 漏洞描述: Bugtraq ID:66358 Zend Framework是一款开放源代码的PHP5开发框架实现. Zend Framework存在多 ...