UVA 10779 (最大流)
题目链接: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 (最大流)的更多相关文章
- AC日记——Collectors Problem uva 10779
UVA - 10779 思路: 最大流: s向所有的贴纸的种类连边,流量为Bob拥有的数量: 然后,Bob的朋友如果没有这种贴纸,则这种贴纸向bob的朋友连边,容量1: 如果bob的朋友的贴纸很多大于 ...
- UVA 10779 Collectors Problem(最大流)
这个题是很难往网络流上面构思的... 从s向每个物品增加容量为Bob拥有数的弧,然后从每个物品向t增加容量为1的弧(代表种类个数).这时候跑最大流的话,得到的肯定是Bob拥有的初始种类数.那么交换后的 ...
- UVa 11082 & 最大流的行列模型
题意: 给出一个矩阵前i行的和与前j列的和,(i∈[1,r],j属于[1,c]),每个元素ai,j∈[1,20],请你还原出这个矩阵,保证有解. SOL: 给网络流建模跪了,神一样的建图,如果我我会怎 ...
- uva 12549 最大流
思路:这题的原型题是比较经典的网络流.原型题模型就是把所有的障碍去掉. 有障碍做法还是一样的,只用将每个列和行重新划分,求最大流就行了. #include <cstring> #inclu ...
- uva 10330 最大流
拆点 将节点 i 的容量拆成从 i 到 i+n 的边的容量 套用最大流模板 ac #include <cstdio> #include <cstdlib> #include ...
- 【网络流#5】UVA 11082 最大流
网络流题目最有意思的地方就是构图了,毕竟套模板每个人都会的 现在有一个矩阵,已知前i行元素之和a[i](1<=i<=n),前j列元素之和b[j](1<=j<=m),求一个可行的 ...
- 【网络流#4】UVA 753 最大流
最近开始刷网络流的题目了,先从紫书上的开始,这道题是P374上的,嘛,总之这道题最终还是参考了一下紫书. 中间是用了STL中map将字符串映射成编号,使用编号总比是用字符串简单的多. 超级源点S与各个 ...
- uva 10779 Collectors Problem 网络流
链接 一共有n个人, m种收藏品, 每个人拥有的收藏品的种类和个数都是不相同的. 假设2-n这些人都只和1互相交换, 比例是1:1, 并且, 2-n这些人, 只换自己现在没有的, 如果他现在有第二种, ...
- UVa 10806 & 费用流+意识流...
题意: 一张无向图,求两条没有重复的从S到T的路径. SOL: 网络流为什么屌呢..因为网络流的容量,流量,费用能对许许多多的问题进行相应的转化,然后它就非常的屌. 对于这道题呢,不是要没有重复吗?不 ...
随机推荐
- [BZOJ1941][Sdoi2010]Hide and Seek
[BZOJ1941][Sdoi2010]Hide and Seek 试题描述 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他 ...
- Struts.xml讲解
解决在断网环境下,配置文件无提示的问题我们可以看到Struts.xml在断网的情况下,前面有一个叹号,这时,我们按alt+/ 没有提示,这是因为” http://struts.apache.org/d ...
- HDU1711
Number Sequence Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- winform 添加“设置文件”
添加配置文件 ·右击服务项目---添加新项---设置文件:----确定 ·把Settings1.settings,拖到properties里,双击Settings1.settings: 名称:是自己定 ...
- hdparm测试硬盘性能
<1>Centos安装hdparm测试硬盘性能 一.安装hdparm yum install hdparm -y Linux学习,http:// linux.it.net.cn 二.评估读 ...
- jdk新特性
自动拆装箱子: import org.junit.Test; public class Demo { /* * 自动拆装箱 * */ @Test public void ZhuangXiang() { ...
- python下的MySQLdb使用
下载安装MySQLdb <1>linux版本 http://sourceforge.net/projects/mysql-python/ 下载,在安装是要先安装setuptools,然后在 ...
- Python学习之字典详解
在元组和列表中,都是通过编号进行元素的访问,但有的时候我们按名字进行数据甚至数据结构的访问,在c++中有map的概念,也就是映射,在python中也提供了内置的映射类型--字典.映射其实就是一组key ...
- hp unix
HP-UNIX 命令大全 #vgdisplay -v vgname #lvdisplay -v lvfullpath #pvdisplay -v pvfullpath # ioscan –fnkC d ...
- 使yum保留下载的rpm包
[root@14LN yum]# egrep 'cachedir|keepcache' /etc/yum.conf #cachedir=/var/cache/yum/$basearch/$releas ...