51nod 1551 集合交易 最大权闭合子图
题意:
市场中有n个集合在卖。我们想买到满足以下要求的一些集合,所买到集合的个数要等于所有买到的集合合并后的元素的个数。
每个集合有相应的价格,要使买到的集合花费最小。
这里我们的集合有一个特点:对于任意整数k(k>0),k个集合的并集中,元素的个数不会小于k个。
现在让你去市场里买一些满足以上条件集合,可以一个都不买。
分析:
根据集合的特点,我们发现,如果吧集合和元素分成左右部,建出二分图,那么一定存在完美匹配。
所以我们把一个集合匹配的那个元素当成它的代表元素。
我们要求最终买到的集合个数要等于并集元素个数。
所以我们如果选择了一个集合,这个集合中除了它的代表元素(设为x),假如还有y元素,而y元素恰好是另一个集合的代表元素,那么我们选择了x代表的集合,就必须选择y代表的那个集合。
这就是最大权闭合子图的模型,选择一个就必须选择另一个。
于是我们把图建出来,根据题目的性质,最后的花费一定不是正数(因为我们可以1个也不选啊),所以当能赚价值的时候,我们就赚,不能赚,我们就一个也不要。
代码:
#include<bits/stdc++.h>
#define ms(a,x) memset(a,x,sizeof(a))
using namespace std;int S,T;bool a[][];
const int N=,M=,inf=;
struct node{int y,z,nxt;}e[M];int q[M],tot;
int o=,h[N],c[N],d[N],m,k,n,ans;bool b[N];
void add(int x,int y,int z){
e[++o]=(node){y,z,h[x]};h[x]=o;
e[++o]=(node){x,,h[y]};h[y]=o;
} bool bfs(){int f=,t=;ms(d,-);
d[S]=;q[++t]=S;
while(f<=t){
int x=q[f++];
for(int i=h[x],y;i;i=e[i].nxt)
if(d[y=e[i].y]==-&&e[i].z)
d[y]=d[x]+,q[++t]=y;
} return (d[T]!=-);
} int dfs(int x,int f){
if(x==T) return f;int w,tmp=;
for(int i=h[x],y;i;i=e[i].nxt)
if(d[y=e[i].y]==d[x]+&&e[i].z){
w=dfs(y,min(e[i].z,f-tmp));
if(!w) d[y]=-;e[i].z-=w;
e[i^].z+=w;tmp+=w;if(tmp==f) return f;
} return tmp;
} void solve(){
while(bfs()) tot+=dfs(S,inf);
} bool hun(int x){
for(int i=;i<=n;i++)
if(a[x][i]&&!b[i]){ b[i]=;
if(!c[i]||hun(c[i]))
{c[i]=x;return ;}
} return ;
} int main(){ tot=ans=;
scanf("%d",&n);S=;T=n+;
for(int i=,x,p;i<=n;i++){
scanf("%d",&p);
while(p--) scanf("%d",&x),a[i][x]=;
} for(int i=;i<=n;i++) ms(b,),hun(i);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(a[i][j]&&c[j]!=i)
add(i,c[j],inf);
for(int i=,x;i<=n;i++){
scanf("%d",&x);x=-x;
if(x<) add(i,T,-x);
else add(S,i,x),ans+=x;
} solve();ans-=tot;
printf("%d\n",ans>?-ans:);return ;
}
最大权闭合子图
51nod 1551 集合交易 最大权闭合子图的更多相关文章
- 51nod 1325 两棵树的问题(最大权闭合子图)
首先如果点权全都为正,就可以直接选所有的点. 活在梦里.. 考虑枚举一个点\(i\),作为我们选择的集合中的一个点. 然后我们把另一个点\(j\)选入集合的时候必须把两棵树中\(i\)和\(j\)路径 ...
- [BZOJ 1497][NOI 2006]最大获利(最大权闭合子图)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1497 分析: 这是在有向图中的问题,且边依赖于点,有向图中存在点.边之间的依赖关系可以 ...
- hiho 第119周 最大权闭合子图
描述 周末,小Hi和小Ho所在的班级决定举行一些班级建设活动. 根据周内的调查结果,小Hi和小Ho一共列出了N项不同的活动(编号1..N),第i项活动能够产生a[i]的活跃值. 班级一共有M名学生(编 ...
- CF 103E Buying Sets 最大权闭合子图,匹配 难度:4
http://codeforces.com/problemset/problem/103/E 这道题首先一看就很像是最大权闭合子图,但是我们可以认为现在有两种点,数字和集合点,我们需要消除数字点的影响 ...
- 洛谷 P2762 太空飞行计划问题 P3410 拍照【最大权闭合子图】题解+代码
洛谷 P2762 太空飞行计划问题 P3410 拍照[最大权闭合子图]题解+代码 最大权闭合子图 定义: 如果对于一个点集合,其中任何一个点都不能到达此集合以外的点,这就叫做闭合子图.每个点都有一个权 ...
- BZOJ1565[NOI2009]植物大战僵尸——最大权闭合子图+拓扑排序
题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻.该款游戏包含多 ...
- 2018.06.27Firing(最大权闭合子图)
Firing Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 11558 Accepted: 3494 Description ...
- 【LYOI 212】「雅礼集训 2017 Day8」价(二分匹配+最大权闭合子图)
「雅礼集训 2017 Day8」价 内存限制: 512 MiB时间限制: 1000 ms 输入文件: z.in输出文件: z.out [分析] 蛤?一开始看错题了,但是也没有改,因为不会做. 一开 ...
- hdu3879 Base Station 最大权闭合子图 边权有正有负
/** 题目:hdu3879 Base Station 最大权闭合子图 边权有正有负 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3879 题意:给出n个 ...
随机推荐
- 【413】C 语言 Command line
Command-Line Arguments All the executable programs above have a main(void) program more generally, e ...
- bzoj 2809: [Apio2012]dispatching【dfs序+主席树】
可并堆就可以,但是想复健一下主席树. 考虑枚举管理者,然后选忍者的时候在子树中贪心的从小到大选.做成dfs序就是选区间内和小于等于k的最多点.可以用主席树,查询的时候在主席树上二分即可 这里注意,为了 ...
- hdu 1348【凸包模板】
#include<iostream> #include<iostream> #include<algorithm> #include<cmath> us ...
- 小程序 video 层级,原生组件
原生组件的层级是最高的,所以页面中的其他组件无论设置 z-index 为多少,都无法盖在原生组件上. 后插入的原生组件可以覆盖之前的原生组件. 原生组件还无法在 scroll-view.swiper. ...
- Lodash 方法库 原生实现 待完结。。。
'use strict' let _ = { // 将数组(array)拆分成多个 size 长度的区块,并将这些区块组成一个新数组. 如果array 无法被分割成全部等长的区块,那么最后剩余的元素将 ...
- WPF-DataGrid(数据表格)美化
我们不多哔哔先上图: 数据表格使用背景: 当我们在做二次开发发现我我们的表格无法向WEB的表格一样好看,这时我们就需要对数据表格进行美化和重构 表格美化思维引导: WPF数据表格是由表头和表体(内容) ...
- PHP arrray_filter(), array_map()区别与应用
array_filter()用回调函数过滤数组中的元素.依次将数组中的元素传递给回调函数,如果回调函数返回true,则被过滤的元素作为返回数组的元素,并最终一起返回.数组的键名保持不变.array_m ...
- 用WEKA进行数据挖掘
学习于IBM教学文档 数据挖掘学习与weka使用 第二部 分分类和集群 分类 vs. 群集 vs. 最近邻 在我深入探讨每种方法的细节并通过 WEKA 使用它们之前,我想我们应该先理解每个模型 - 每 ...
- Coins HDU - 2844 POJ - 1742
Coins HDU - 2844 POJ - 1742 多重背包可行性 当做一般多重背包,二进制优化 #include<cstdio> #include<cstring> in ...
- 面试王牌 JAVA 多态只针对方法 不针对属性
子类是永远继承父类的非私有化方法,当子类中重写父类方法时,调用的是子类的方法,没有重写时,调用的是父类中的方法 1 多态是只针对方法,而不是属性的,但是写法上,子类重写父类的属性,编译器是不会报错的 ...