有n(20)个工程,完成每个工程获得收益是p[i],m(50)个需要解决的难题,解决每个难题花费是c[i]

要完成第i个工程,需要先解决ki个问题,具体哪些问题,输入会给出

每个难题之间可能有依赖关系,比如i->j就是解决问题j需要实现解决问题i。(题目描述有问题,但是按照样例来看,是前后说反了,也就是按照题意这个地方反向建图就可以)

问,最大收益可以是多少

比较裸的最大权闭合图,解决最大权闭合图一般用最大流的方法

然而训练的时候并不知道这个,所以结束后看了看相关的资料,

下面仅说明一下建图方法。

建立一个源点S,s向每个工程点连一条边,权值是p[i],

建立一个汇点T,t向每个问题连一条边,权值是c[i]

接着,工程与完成工程需要的解决的问题,连一条边,权值INF

难题之间按照题目连边,权值仍为INF

求出最大流maxflow

答案就是sigema(p[i])-maxflow

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<cmath>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<set>
  7. #include<map>
  8. #include<stack>
  9. #include<vector>
  10. #include<queue>
  11. #include<string>
  12. #include<sstream>
  13. #define eps 1e-9
  14. #define ALL(x) x.begin(),x.end()
  15. #define INS(x) inserter(x,x.begin())
  16. #define FOR(i,j,k) for(int i=j;i<=k;i++)
  17. #define MAXN 1005
  18. #define MAXM 40005
  19. #define INF 0x3fffffff
  20. #define PB push_back
  21. #define MP make_pair
  22. #define X first
  23. #define Y second
  24. #define lc (k<<1)
  25. #define rc ((k<<1)1)
  26. #define V(x) vector<x >
  27. #define vs V(string)
  28. #define vi V(int)
  29. #define fr(x,y,z) for ((x)=(y);(x)<(z);(x)++)
  30. #define fo(x,y) fr(x,0,y)
  31. #define fir(n) fo(i,n)
  32. #define fjr(n) fo(j,n)
  33. #define fkr(n) fo(k,n)
  34. #define fi fir(n)
  35. #define fj fjr(n)
  36. #define fk fkr(n)
  37. #define pb push_back
  38. #define sz size()
  39. #define cs c_str()
  40. #define clr(x,y) memset((x),(y),sizeof(x))
  41. #define df double
  42. using namespace std;
  43. typedef long long LL;
  44. int i,j,k,n,m,x,y,T,ans,big,cas,num,len;
  45. bool flag;
  46.  
  47. const int inf = 0x3f3f3f3f;
  48. struct edgenode
  49. {
  50. int from,to,next;
  51. int cap;
  52. }edge[MAXM];
  53. int Edge,head[MAXN],ps[MAXN],dep[MAXN];
  54.  
  55. void add_edge(int x,int y,int c)
  56. {
  57. edge[Edge].from=x;
  58. edge[Edge].to=y;
  59. edge[Edge].cap=c;
  60. edge[Edge].next=head[x];
  61. head[x]=Edge++;
  62.  
  63. edge[Edge].from=y;
  64. edge[Edge].to=x;
  65. edge[Edge].cap=;
  66. edge[Edge].next=head[y];
  67. head[y]=Edge++;
  68. }
  69.  
  70. int dinic(int n,int s,int t)
  71. {
  72. int tr,flow=;
  73. int i,j,k,l,r,top;
  74. while(){
  75. memset(dep,-,(n+)*sizeof(int));
  76. for(l=dep[ps[]=s]=,r=;l!=r;)//BFS部分,将给定图分层
  77. {
  78. for(i=ps[l++],j=head[i];j!=-;j=edge[j].next)
  79. {
  80. if (edge[j].cap&&-==dep[k=edge[j].to])
  81. {
  82. dep[k]=dep[i]+;ps[r++]=k;
  83. if(k==t)
  84. {
  85. l=r;
  86. break;
  87. }
  88. }
  89. }
  90. }
  91. if(dep[t]==-)break;
  92.  
  93. for(i=s,top=;;)//DFS部分
  94. {
  95. if(i==t)//当前点就是汇点时
  96. {
  97. for(k=,tr=inf;k<top;++k)
  98. if(edge[ps[k]].cap<tr)tr=edge[ps[l=k]].cap;
  99.  
  100. for(k=;k<top;++k)
  101. edge[ps[k]].cap-=tr,edge[ps[k]^].cap+=tr;
  102.  
  103. flow+=tr;
  104. i=edge[ps[top=l]].from;
  105. }
  106.  
  107. for(j=head[i];j!=-;j=edge[j].next)//找当前点所指向的点
  108. if(edge[j].cap&&dep[i]+==dep[edge[j].to]) break;
  109.  
  110. if(j!=-)
  111. {
  112. ps[top++]=j;//当前点有所指向的点,把这个点加入栈中
  113. i=edge[j].to;
  114. }
  115. else
  116. {
  117. if (!top) break;//当前点没有指向的点,回溯
  118. dep[i]=-;
  119. i=edge[ps[--top]].from;
  120. }
  121. }
  122. }
  123. return flow;
  124. }
  125.  
  126. int p[MAXN],c[MAXN],t;
  127.  
  128. int main()
  129. {
  130. scanf("%d",&T);
  131. while (T--)
  132. {
  133. memset(head,-,sizeof(head));
  134. Edge=;
  135. scanf("%d%d",&n,&m);
  136. int sum=;
  137. for (i=;i<n;i++)
  138. {
  139. scanf("%d",&p[i]);
  140. add_edge(,i+,p[i]);
  141. sum+=p[i];
  142. }
  143. for (i=;i<m;i++)
  144. {
  145. scanf("%d",&c[i]);
  146. add_edge(n++i,n+m+,c[i]);
  147. }
  148. for (i=;i<n;i++)
  149. {
  150. scanf("%d",&k);
  151. //E[i].clear();
  152. for (j=;j<k;j++)
  153. {
  154. scanf("%d",&t);
  155. add_edge(i+,t+n+,INF);
  156. //E[i].PB(t);
  157. }
  158. }
  159.  
  160. for (i=;i<m;i++)
  161. {
  162. for (j=;j<m;j++)
  163. {
  164. scanf("%d",&t);
  165. if (t)
  166. {
  167. add_edge(i++n,j++n,INF);
  168. }
  169. }
  170. }
  171.  
  172. printf("Case #%d: %d\n",++cas,sum-dinic(m+n+,,n+m+));
  173.  
  174. }
  175. return ;
  176. }

HDU 4971 - A simple brute force problem【最大权闭合图】的更多相关文章

  1. HDU 4971 A simple brute force problem.

    A simple brute force problem. Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged o ...

  2. hdu - 4971 - A simple brute force problem.(最大权闭合图)

    题意:n(n <= 20)个项目,m(m <= 50)个技术问题,做完一个项目能够有收益profit (<= 1000),做完一个项目必须解决对应的技术问题,解决一个技术问题须要付出 ...

  3. 【最小割】HDU 4971 A simple brute force problem.

    说是最大权闭合图.... 比赛时没敢写.... 题意 一共同拥有n个任务,m个技术 完毕一个任务可盈利一些钱,学习一个技术要花费钱 完毕某个任务前须要先学习某几个技术 可是可能在学习一个任务前须要学习 ...

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

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

  5. A simple brute force problem.

    hdu4971:http://acm.hdu.edu.cn/showproblem.php?pid=4971 题意:给你n个项目,每完成一个项目会有一定的收益,但是为了完成某个项目,要先学会一些技能, ...

  6. HDU5772 String problem 最大权闭合图+巧妙建图

    题意:自己看吧(不是很好说) 分析: 网络流:最大权闭合子图. 思路如下: 首先将点分为3类 第一类:Pij 表示第i个点和第j个点组合的点,那么Pij的权值等于w[i][j]+w[j][i](表示得 ...

  7. hdu 4972 A simple dynamic programming problem(高效)

    pid=4972" target="_blank" style="">题目链接:hdu 4972 A simple dynamic progra ...

  8. HDU 3879 && BZOJ 1497:Base Station && 最大获利 (最大权闭合图)

    http://acm.hdu.edu.cn/showproblem.php?pid=3879 http://www.lydsy.com/JudgeOnline/problem.php?id=1497 ...

  9. hdu 3061 Battle 最大权闭合图

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3061 由于小白同学近期习武十分刻苦,很快被晋升为天策军的统帅.而他上任的第一天,就面对了一场极其困难的 ...

随机推荐

  1. Windows Azure 配置SSTP

    方法參考下面文章的步驟. 这个成功.http://freevpnba.com/windows-azure-sstp-vpn/ 这个没成功,不知道为什么.http://diaosbook.com/pos ...

  2. 学习VI的强文,新工作需要呀

    http://www.gentoo.org/doc/zh_cn/vi-guide.xml :set nu//用于给文本加行号的. :set nocompatible //启用 vi 兼容模式,一般是给 ...

  3. [jobdu]调整数组顺序使奇数位于偶数前面

    这道题的代码没啥好说的,用了O(n)的空间就是水题了.但可以讲一下思考过程.一开始是想O(1)的空间的,然后想从左往右双指针扫,然后根据出现顺序交换遇到的偶数和奇数.但遇到一个问题:1, 2, 3, ...

  4. 1044 - Palindrome Partitioning(区间DP)

    题目大意: 给你一个字符串,问这个字符串最少有多少个回文串. 区间DP直接搞     #include<cstdio> #include<cstring> #include&l ...

  5. (转载)mysql_query( )返回值

    (转载)http://hi.baidu.com/tfbzccqceabfhyd/item/bd01db9f8995204af04215e4 调用mysql_query( ),当查询操作是update. ...

  6. CnPack for delphi xe5

    CnPack Team is made up of Chinese Programmers and Delphi / C++ Builder fans across the Internet. Our ...

  7. HDOJ 1081(ZOJ 1074) To The Max(动态规划)

    Problem Description Given a two-dimensional array of positive and negative integers, a sub-rectangle ...

  8. Tomcat绑定多个IP地址 多域名绑定

    http://blog.csdn.net/stevenyanzhi/article/details/6029776 Tomcat绑定多个IP地址 如果一台服务机上有多个IP地址又有多个工程如何一个IP ...

  9. poj 1985 Cow Marathon【树的直径裸题】

    Cow Marathon Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 4185   Accepted: 2118 Case ...

  10. selenium.common.exceptions.TimeoutException: Message: Screenshot: available via screen

    在使用selenium+phantomjs的时候在Windows平台下能够正常工作,在Linux下却不能,并得到错误信息: selenium.common.exceptions.TimeoutExce ...