http://codeforces.com/problemset/problem/103/E

这道题首先一看就很像是最大权闭合子图,但是我们可以认为现在有两种点,数字和集合点,我们需要消除数字点的影响才能直接运用最大权闭合子图.

进行二分匹配,使得每个集合都唯一匹配一个数字,买下一个集合点,则意味着该集合中所有数字的对应匹配集合点都要被买下,也就是可以建立一个新图,其中某个集合点向对应数字代表的集合点连单向边,可以证明对于任意权闭合子图中的集合点,集合中所有数字的对应匹配集合点都已经在这个权闭合子图中.对这个新图的所有价格取反,答案即最大权的负数

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int maxn=305;
  6. const int maxm=2*maxn+maxn*maxn;
  7. const int sups=303,supt=304;
  8. const int inf=0x6ffffff;
  9.  
  10. int n;//original aspects
  11. int price[maxn];
  12. int st[maxn][maxn],nst[maxn];
  13.  
  14. int mch[2*maxn];//Match
  15. bool vis[2*maxn];
  16.  
  17. int first[maxn],elen;//maximum flow
  18. struct edge{
  19. int nxt,f,t,c;
  20. }e[maxm];
  21. int dis[maxn],gap[maxn];
  22.  
  23. bool subMatch(int s){
  24. vis[s]=true;
  25. for(int j=0;j<nst[s];j++){
  26. int t=st[s][j]+n;
  27. if(vis[t]||mch[t]==s)continue;
  28. if(mch[t]==0||(!vis[mch[t]]&&subMatch(mch[t]))){
  29. mch[t]=s;
  30. mch[s]=t;
  31. return true;
  32. }
  33. }
  34. return false;
  35. }
  36. void Match(){
  37. for(int i=1;i<=n;i++){
  38. if(mch[i]==0){
  39. memset(vis,false,sizeof(vis));
  40. subMatch(i);
  41. }
  42. }
  43. }
  44.  
  45. void addedge(int f,int t,int c){
  46. e[elen].nxt=first[f];
  47. e[elen].f=f;
  48. e[elen].t=t;
  49. e[elen].c=c;
  50. first[f]=elen++;
  51. }
  52. void build(){
  53. for(int i=1;i<=n;i++){
  54. if(price[i]>=0){
  55. addedge(sups,i,price[i]);
  56. addedge(i,sups,0);
  57. }
  58. else {
  59. addedge(i,supt,-price[i]);
  60. addedge(supt,i,0);
  61. }
  62. for(int j=0;j<nst[i];j++){
  63. int t=mch[st[i][j]+n];
  64. addedge(i,t,inf);
  65. addedge(t,i,0);
  66. }
  67. }
  68. }
  69. int dfs(int s,int flow){
  70. if(s==supt)return flow;
  71. int mindis=n;
  72. int tflow=flow,sub;
  73. for(int p=first[s];p!=-1;p=e[p].nxt){
  74. int t=e[p].t;
  75. if(e[p].c>0){
  76. if(dis[t]+1==dis[s]){
  77. sub=dfs(t,min(tflow,e[p].c));
  78. e[p].c-=sub;e[p^1].c+=sub;
  79. tflow-=sub;
  80. if(dis[sups]>n)return flow-tflow;
  81. if(tflow<=0)break;
  82. }
  83. mindis=min(mindis,dis[t]);
  84. }
  85. }
  86. if(flow==tflow){
  87. --gap[dis[s]];
  88. if(gap[dis[s]]==0)dis[sups]=n+1;
  89. else{
  90. dis[s]=mindis+1;
  91. ++gap[dis[s]];
  92. }
  93. }
  94. return flow-tflow;
  95. }
  96. int maxflow(){
  97. int flow=0;
  98. gap[0]=n+2;
  99. while(dis[sups]<=n){
  100. flow+=dfs(sups,inf);
  101. }
  102. return flow;
  103. }
  104.  
  105. int main(){
  106. int ans=0;
  107. memset(first,-1,sizeof(first));
  108. scanf("%d",&n);
  109. for(int i=1;i<=n;i++){
  110. scanf("%d",nst+i);
  111. for(int j=0;j<nst[i];j++){
  112. scanf("%d",st[i]+j);
  113. }
  114. }
  115. for(int i=1;i<=n;i++){
  116. scanf("%d",price+i);
  117. price[i]*=-1;
  118. if(price[i]>=0)ans+=price[i];
  119. }
  120.  
  121. Match();
  122. build();
  123. ans=maxflow()-ans;
  124. printf("%d\n",ans);
  125. return 0;
  126. }

CF 103E Buying Sets 最大权闭合子图,匹配 难度:4的更多相关文章

  1. 洛谷 P4174 [NOI2006]最大获利 && 洛谷 P2762 太空飞行计划问题 (最大权闭合子图 && 最小割输出任意一组方案)

    https://www.luogu.org/problemnew/show/P4174 最大权闭合子图的模板 每个通讯站建一个点,点权为-Pi:每个用户建一个点,点权为Ci,分别向Ai和Bi对应的点连 ...

  2. Solution -「最大权闭合子图」做题随笔

    T1 小 M 的作物 先从简化题目入手,考虑先去掉 \(c\) 的额外收益.然后尝试将所有作物种在 \(B\), 则目前得到了 \(\sum \limits_{i = 1} ^n b_i\) 的收益. ...

  3. BZOJ1565 [NOI2009]植物大战僵尸(拓扑排序 + 最大权闭合子图)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=1565 Description Input Output 仅包含一个整数,表示可以 ...

  4. HDU 3879 Base Station(最大权闭合子图)

    经典例题,好像说可以转化成maxflow(n,n+m),暂时只可以勉强理解maxflow(n+m,n+m)的做法. 题意:输入n个点,m条边的无向图.点权为负,边权为正,点权为代价,边权为获益,输出最 ...

  5. [BZOJ 1497][NOI 2006]最大获利(最大权闭合子图)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1497 分析: 这是在有向图中的问题,且边依赖于点,有向图中存在点.边之间的依赖关系可以 ...

  6. HDU4971 A simple brute force problem.(强连通分量缩点 + 最大权闭合子图)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4971 Description There's a company with several ...

  7. HDU5855 Less Time, More profit(最大权闭合子图)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5855 Description The city planners plan to build ...

  8. HDU5772 String problem(最大权闭合子图)

    题目..说了很多东西 官方题解是这么说的: 首先将点分为3类 第一类:Pij 表示第i个点和第j个点组合的点,那么Pij的权值等于w[i][j]+w[j][i](表示得分) 第二类:原串中的n个点每个 ...

  9. SCU3109 Space flight(最大权闭合子图)

    嗯,裸的最大权闭合子图. #include<cstdio> #include<cstring> #include<queue> #include<algori ...

随机推荐

  1. mysql 性能问题

    1.场景,模拟一天的数据,每个10秒,遍历1000个设备,每个设备模拟一个实时数据,总的数据量为:24*60*60/10*1000 = 864万条记录.2.采用策略,对时间分段,拼接sql语句查询,对 ...

  2. css 常用样式命名规则

    大家在写css的时候,对一些html标签起一个合适的名字是个很头疼的事情,现在给大家分享项目中常用的名字供参考. 外套:wrap  ——用于最外层 头部:header  ——用于头部 主要内容:mai ...

  3. 【转载】Spark系列之运行原理和架构

    参考 http://www.cnblogs.com/shishanyuan/p/4721326.html 1. Spark运行架构 1.1 术语定义 lApplication:Spark Applic ...

  4. Android 可拖动列表项的ListView

    需求分析 一个界面内两个ListView 我关注的栏目列表 上面的要长按后可拖动排序 点击减号后列表项消失 下面列表增加一行 同时存储相应字符串到本地作为标记 未关注栏目列表 普通ListView 点 ...

  5. Openfire 是怎么存离线消息

    原文:http://myopenfire.com/article/getarticle/26 1.openfire默认怎么存离线消息   在默认情况下,不添加任何插件的情况下,当用户不在线,对于发送给 ...

  6. OpenGL的glTexCoord2f纹理坐标配置

    纹理坐标配置函数,先看定义: void glTexCoord2f (GLfloat s, GLfloat t); 1.glTexCoord2f()函数 有两个参数:GLfloat s, GLfloat ...

  7. 自我总结(五)---(学习j2ee)

    自我完善的过程就是在不断的自我总结不断的改进. 我们这半个月来都是学习j2ee.这个知识是很重要的,一般我们出去工作都是会用到的.我们的星期六,星期天也是不上课的.所以说我相当于上了十天的j2ee了. ...

  8. 数据库索引B+树

    面试时无意间被问到了这个问题:数据库索引的存储结构一般是B+树,为什么不适用红黑树等普通的二叉树? 经过和同学的讨论,得到如下几个情况: 1. 数据库文件是放在硬盘上,每次读取数据库都需要在磁盘上搜索 ...

  9. vs调试 LINK : fatal error LNK1104 ...exe

    出现错误 LINK : fatal error LNK1104  ...exe (1)任务管理器中杀死...exe (2)此工程是复制过来的,但之前的已经装入内存,所以不能打开.重启VS即可.

  10. 使用Objective-C的文档生成工具

    前言 做项目的人多了,就需要文档了.今天开始尝试写一些项目文档.但是就源代码来说,文档最好和源码在一起,这样更新起来更加方便和顺手.象Java语言本身就自带javadoc命令,可以从源码中抽取文档.今 ...