题意:

Bob和他的朋友从糖果包装里手机贴纸。这些朋友每人手里都有一些(可能有重复的)贴纸,并且只跟别人交换他所没有的贴纸,贴纸总是一对一交换。

Bob比这些朋友更聪明,因为他意识到只跟别人交换自己没有的贴纸并不总是最优的。在某些情况下,换来一张重复的贴纸更划算。

假设Bob的朋友只和Bob交换(他们之间不交换),并且这些朋友只会出让手里的重复贴纸来交换他们没有的不同贴纸。你的任务是帮助Bob算出他最终可以得到的不同贴纸的最大数量。

分析:

建n-1个点(除Bob以外的每个人)和m个点(每个物品)从s向每个物品连边,容量为拥有该物品的数量。如果某人已经至少拥有两个物品j,那么就从i向j连边,容量为拥有的物品数-1;如果没有物品j,就从j向i连边。

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue> using namespace std;
const int maxn=+;
const int maxm=;
const int INF=;
struct Dinic{
int head[maxn],Next[maxn],to[maxn],cap[maxn],flow[maxn];
int sz,n,m,s,t;
bool vis[maxn];
int cur[maxn],d[maxn];
void init(int n){
this->n=n;
memset(head,-,sizeof(head));
this->sz=-;
}
void add_edge(int a,int b,int c){
++sz;
to[sz]=b;
cap[sz]=c;flow[sz]=;
Next[sz]=head[a];head[a]=sz;
++sz;
to[sz]=a;
cap[sz]=c;flow[sz]=c;
Next[sz]=head[b];head[b]=sz;
}
bool BFS(){
memset(vis,,sizeof(vis));
queue<int>Q;
vis[s]=;
d[s]=;
Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=head[u];i!=-;i=Next[i]){
int v=to[i];
if(!vis[v]&&cap[i]>flow[i]){
vis[v]=;
d[v]=d[u]+;
Q.push(v);
}
}
}
return vis[t];
}
int DFS(int x,int a){
if(x==t||a==)return a;
int Flow=,f;
for(int& i=cur[x];i!=-;i=Next[i]){
int v=to[i];
if(d[v]==d[x]+&&(f=DFS(v,min(a,cap[i]-flow[i])))>){
Flow+=f;
flow[i]+=f;
flow[i^]-=f;
a-=f;
if(a==)break;
}
}
return Flow;
}
int Maxflow(int s,int t){
this->s=s,this->t=t;
int Flow=;
while(BFS()){
for(int i=;i<=n;i++)
cur[i]=head[i]; Flow+=DFS(s,INF);
}
return Flow;
}
}dinic;
int n,m,T,kase;
int main(){
kase=;
scanf("%d",&T);
for(int t=;t<=T;t++){
++kase;
scanf("%d%d",&n,&m);
dinic.init(n+m+);
int a[maxm];
dinic.s=;dinic.t=n+m+;
for(int i=;i<=n;i++){
int num;
scanf("%d",&num);
memset(a,,sizeof(a));
for(int j=;j<=num;j++){
int aa;
scanf("%d",&aa);
a[aa]++;
}
if(i==){
for(int j=;j<=m;j++){
if(a[j])
dinic.add_edge(,n+j,a[j]);
}
}else{
for(int j=;j<=m;j++){
if(a[j]>=){
dinic.add_edge(i,n+j,a[j]-);
}
if(a[j]==){
dinic.add_edge(n+j,i,);
}
}
}
}
for(int i=;i<=m;i++)
dinic.add_edge(i+n,dinic.t,);
int ans=dinic.Maxflow(,dinic.t);
printf("Case #%d: %d\n",kase,ans);
}
return ;
}

【UVA10079 训练指南】收集者的难题【最大流】的更多相关文章

  1. 【LA2531 训练指南】足球联赛 【最大流】

    题意: 有n支队伍进行比赛,每支队伍需要打的比赛数目相同.每场比赛恰好一支队伍胜,另一支败.给出每支队伍目前胜的场数和败的场数,以及每两支队伍还剩下的比赛场数,确定所有可能的冠军的球队.(获胜场数最多 ...

  2. 【LA11248 训练指南】网络扩容【最大流】

    题意: 给定一个有向网络,每条边均有一个容量.问是否存在一个从点1到点N,流量为C的流.如果不存在,是否可以恰好修改一条弧的容量,使得存在这样的流? 分析: 先跑一遍最大流,如果最大流大于等于C,则输 ...

  3. poj 1961 Period(KMP训练指南例题)

    Period Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 11356   Accepted: 5279 Descripti ...

  4. 算法竞赛入门经典训练指南——UVA 11300 preading the Wealth

    A Communist regime is trying to redistribute wealth in a village. They have have decided to sit ever ...

  5. [置顶] 刘汝佳《训练指南》动态规划::Beginner (25题)解题报告汇总

    本文出自   http://blog.csdn.net/shuangde800 刘汝佳<算法竞赛入门经典-训练指南>的动态规划部分的习题Beginner  打开 这个专题一共有25题,刷完 ...

  6. 【UVA11107 训练指南】Life Forms【后缀数组】

    题意 输入n(n<=100)个字符串,每个字符串长度<=1000,你的任务是找出一个最长的字符串使得超过一半的字符串都包含这个字符串. 分析 训练指南上后缀数组的一道例题,据说很经典(估计 ...

  7. 【LA3523 训练指南】圆桌骑士 【双连通分量】

    题意 有n个骑士经常举行圆桌会议,商讨大事.每次圆桌会议至少应有3个骑士参加,且相互憎恨的骑士不能坐在圆桌旁的相邻位置.如果发生意见分歧,则需要举手表决,因此参加会议的骑士数目必须是奇数,以防赞同和反 ...

  8. 训练指南 UVALive - 3126(DAG最小路径覆盖)

    layout: post title: 训练指南 UVALive - 3126(DAG最小路径覆盖) author: "luowentaoaa" catalog: true mat ...

  9. 训练指南 UVALive - 3415(最大点独立集)

    layout: post title: 训练指南 UVALive - 3415(最大点独立集) author: "luowentaoaa" catalog: true mathja ...

随机推荐

  1. caddy server 了解

    Caddy 是一个Go写的服务器软件,官方的宣传语“The HTTP/2 web server with automatic HTTPS”以及“Serve The Web Like It's 2016 ...

  2. [深度学习]Wake-Sleep算法

    本文翻译自2007-To recognize shapes, first learn to generate images, Geoffrey Hinton. 第五种策略的设计思想是使得高层的特征提取 ...

  3. filter异常捕捉

    jsp中抛出一个异常 <% String action = request.getParameter("action"); if ("accountExceptio ...

  4. vim初探

    https://github.com/spf13/spf13-vim 安装了此博主的开源项目. :vsp   ——竖分屏 :sp   ——横分屏

  5. SharePoint2013集成Exchange之任务同步

    SharePoint可以将任务列表到outlook中,但在sharepoint 2013 上这个功能似乎不是很好用,如下图所示,点击任务列表的"同步到Outlook"按钮: 在弹出 ...

  6. Java并发-Runnable、Callable、Future、Future Task

    Runnable: Runnable的代码非常简单,他是一个接口,且接口中只有一个方法,run(),创建一个类实现他,把一些费时操作写在其中,然后使用某个线程去执行该Runnable实现类即可实现多线 ...

  7. 第十章 Secret & Configmap (中)

    10.3 在Pod中使用Secret 10.3.1 Volume方式 apiVersion: v1 kind: Pod metaata: name: mypod spec: containers: - ...

  8. PyQt 5控件

    PyQt 5控件包括:按钮.复选框.滑动条.列表框等 复选框QCheckBox QCheckBox复选框控件,它有两个状态:打开和关闭,他是一个带有文本标签(Label)的控件.复选框常用于表示程序中 ...

  9. 【转】浅析VO、DTO、DO、PO的概念、区别和用处

    原文地址:http://blog.csdn.net/zjrbiancheng/article/details/6253232 概念: VO(View Object):视图对象,用于展示层,它的作用是把 ...

  10. 第一章 : Android Studio 介绍 [Learn Android Studio 汉化教程]

    摘自:http://ask.android-studio.org/?/question/789,为便于学习重新整理.. 本章将引导您完成安装和设置开发环境,然后你就可以跟随本书的例子和课程学习. 首先 ...