题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33631

题目大意:Bob有一些贴纸,他可以和别人交换,他可以把自己独有的贴纸拿出去,也可以把重复的贴纸拿出去(有时候把独有的贴纸而不是重复的贴纸拿出去能换到更多贴纸)。

Bob的朋友也有一些贴纸,但是他们只会拿自己重复的贴纸和Bob换,而且换的是自己没有的贴纸。

求Bob最后最多能有多少种贴纸。

解题思路

题目意思很明确了。就算把重复的贴纸拿出去也不一定最优,贪心就不用尝试了。

全局资源调配得使用网络流模型。

建图方式:

①S点(看作是Bob)->所有物品:连一条边,cap是Bob持有贴纸数量。

②:所有朋友->所有物品:如果这个人持有的该贴纸数量>=2,连一条边,cap是贴纸数量-1。(原因是这些人只会把重复的贴纸拿出去)。

③:所有物品->所有朋友:如果这个人没有改物品,连一条边,cap=1,。(原因是这些人会接受自己没有的贴纸)

④:所有物品->T点:连一条边,cap=1,统计物品的种类。

这样建图之后,所有物品可以看作Bob的总资产,这个总资产可以流进,也可以流出,在这基础上做一次最大流,就是结果了。

代码使用比较坑爹的边表,虽然速度不如链式前向星,但是ISAP+gap优化+当前弧优化已经足够快了。

#include "cstdio"
#include "vector"
#include "cstring"
#include "queue"
using namespace std;
#define maxn 405
#define inf 100000000
struct Edge
{
int from,to,cap,flow;
Edge(int FROM,int TO,int CAP,int FLOW):from(FROM),to(TO),cap(CAP),flow(FLOW) {}
};
int d[maxn],p[maxn],gap[maxn],cur[maxn],paste[][];
bool vis[maxn];
vector<int> G[maxn];
vector<Edge> edges;
void addedge(int from,int to,int cap)
{
edges.push_back(Edge(from,to,cap,));
edges.push_back(Edge(to,from,,));
int m=edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
}
void bfs(int s,int t)
{
memset(vis,false,sizeof(vis));
memset(d,,sizeof(d));
memset(p,,sizeof(p));
d[t]=;vis[t]=true;
queue<int> Q;Q.push(t);
while(!Q.empty())
{
int u=Q.front();Q.pop();
for(int v=;v<G[u].size();v++)
{
Edge e=edges[G[u][v]^];
if(!vis[e.from]&&e.cap>e.flow)
{
vis[e.from]=true;
d[e.from]=d[u]+;
Q.push(e.from);
}
}
}
}
int augment(int s,int t)
{
int x=t,a=inf;
while(x!=s)
{
Edge e=edges[p[x]];
a=min(a,e.cap-e.flow);
x=e.from;
}
x=t;
while(x!=s)
{
edges[p[x]].flow+=a;
edges[p[x]^].flow-=a;
x=edges[p[x]].from;
}
return a;
}
int maxflow(int s,int t)
{
int flow=,u=s;
bfs(s,t);
memset(gap,,sizeof(gap));
memset(cur,,sizeof(cur));
for(int i=;i<=t;i++) gap[d[i]]++;
while(d[s]<t+)
{
if(u==t)
{
flow+=augment(s,t);
u=s;
}
bool flag=false;
for(int v=cur[u];v<G[u].size();v++) //Advance
{
Edge e=edges[G[u][v]];
if(e.cap>e.flow&&d[u]==d[e.to]+)
{
flag=true;
p[e.to]=G[u][v];
cur[u]=v;
u=e.to;
break;
}
}
if(!flag) //Retreat
{
int m=t+;
for(int v=;v<G[u].size();v++)
{
Edge e=edges[G[u][v]];
if(e.cap>e.flow) m=min(m,d[e.to]);
}
if(--gap[d[u]]==) break;
gap[d[u]=m+]++;
cur[u]=;
if(u!=s) u=edges[p[u]].from;
}
}
return flow;
}
int main()
{
int T,n,k,id,num,no=;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++)
{
scanf("%d",&num);
for(int j=;j<=num;j++)
{
scanf("%d",&id);
paste[i][id]++;
}
}
for(int i=;i<=k;i++) //S->Bob
if(paste[][i]) {addedge(,i,paste[][i]);}
for(int i=;i<=n;i++) //Bob->friends
for(int j=;j<=k;j++)
{
if(paste[i][j]>=) addedge(k+i,j,paste[i][j]-);
if(!paste[i][j]) addedge(j,k+i,);
}
for(int i=;i<=k;i++) addedge(i,k+n+,);//Bob->T
printf("Case #%d: %d\n",++no,maxflow(,k+n+));
for(int i=;i<maxn;i++) G[i].clear();
edges.clear();
memset(paste,,sizeof(paste));
}
}
2817630 neopenx UVA 10779 Accepted 0 KB 16 ms C++ 4.8.2 3270 B 2014-10-05 13:48:15  

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

  1. AC日记——Collectors Problem uva 10779

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

  2. UVA 10779 Collectors Problem(最大流)

    这个题是很难往网络流上面构思的... 从s向每个物品增加容量为Bob拥有数的弧,然后从每个物品向t增加容量为1的弧(代表种类个数).这时候跑最大流的话,得到的肯定是Bob拥有的初始种类数.那么交换后的 ...

  3. UVa 11082 & 最大流的行列模型

    题意: 给出一个矩阵前i行的和与前j列的和,(i∈[1,r],j属于[1,c]),每个元素ai,j∈[1,20],请你还原出这个矩阵,保证有解. SOL: 给网络流建模跪了,神一样的建图,如果我我会怎 ...

  4. uva 12549 最大流

    思路:这题的原型题是比较经典的网络流.原型题模型就是把所有的障碍去掉. 有障碍做法还是一样的,只用将每个列和行重新划分,求最大流就行了. #include <cstring> #inclu ...

  5. uva 10330 最大流

    拆点  将节点 i 的容量拆成从 i 到 i+n 的边的容量 套用最大流模板 ac #include <cstdio> #include <cstdlib> #include ...

  6. 【网络流#5】UVA 11082 最大流

    网络流题目最有意思的地方就是构图了,毕竟套模板每个人都会的 现在有一个矩阵,已知前i行元素之和a[i](1<=i<=n),前j列元素之和b[j](1<=j<=m),求一个可行的 ...

  7. 【网络流#4】UVA 753 最大流

    最近开始刷网络流的题目了,先从紫书上的开始,这道题是P374上的,嘛,总之这道题最终还是参考了一下紫书. 中间是用了STL中map将字符串映射成编号,使用编号总比是用字符串简单的多. 超级源点S与各个 ...

  8. uva 10779 Collectors Problem 网络流

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

  9. UVa 10806 & 费用流+意识流...

    题意: 一张无向图,求两条没有重复的从S到T的路径. SOL: 网络流为什么屌呢..因为网络流的容量,流量,费用能对许许多多的问题进行相应的转化,然后它就非常的屌. 对于这道题呢,不是要没有重复吗?不 ...

随机推荐

  1. (转)WPF控件开源资源

    (转)WPF控件开源资源 Textbox Drag/Drop in WPFhttp://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in- ...

  2. 纯Java获得本地MAC地址

    import java.net.*; public class Ipconfig{      public static void main(String[] arguments) throws Ex ...

  3. 在Windows Server 2012 中安装 .NET 3.5 Framework

    问题 如今,仍然有许多程序和应用需要依靠.NET 3.5 framework 来运行.在Windows Server 2012中,微软提供了.NET 3.5 和.NET 4.5的安装选项以为你的应用程 ...

  4. (转)女生应该找一个玩ACM的男生

    1.强烈的事业心 将来,他也一定会有自己热爱的事业.而且,男人最性感的时刻之一,就是他专心致志做事的时候.所以,找一个机会在他全神贯注玩ACM的时候,从侧面好好观察他,你就会发现我说的话没错. 2.永 ...

  5. Linux tar命令exclude选项排除指定文件或目录

    在linux中可以用tar打包目录以方便传输or备份,我们先来看一个例子 test 文件夹有如下文件 [root@lee ~]# ll test 总用量 -rw-r--r--. root root 4 ...

  6. MVC(Model(模型) View(视图) Controller(控制器))

    复习 1.      商品表 增删改查 index.php  add.php   view.php   edit.php   action.php 2.      MVC(Model(模型)  Vie ...

  7. digitalocean添加ssh_keys

    链接为: https://cloud.digitalocean.com/settings/security

  8. 【云计算】开源装机自动化系统 CloudBoot OSInstall 介绍

    "CloudBoot"(OSinstall) 发布了. 产品更新及特点如下: 新增虚拟化操作系统适配:支持主流操作系统:RedHat.CentOS.SUSE.Ubuntu.Wind ...

  9. Eclipse 一直提示 loading descriptor for 的解决方法(转)

    启动eclipse之后,进行相关操作时,弹出界面,提示:loading descriptor for xxx 解决方法: 在Eclipse左侧的Project Explorer 最右上角有一个小钮,鼠 ...

  10. spring3 + mybatis + maven:junit测试错误

    org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component c ...