题目大概一个国家n个城市由m条单向边相连,摧毁每条边都有一个费用。现在你可以选择所给的f个城市中的若干个,每个城市选择后都有一定的价值,但首都1号城市必须到达不了你选择的城市,因为你可能需要摧毁一些边,这样你的获利就是选择城市的价值和减摧毁边的总花费。问,最大的获利是多少以及摧毁哪些边。

如此建容量网络:首都作为源点,原图中单向边的容量设为摧毁边的费用,所有可以选择的城市与汇点相连容量为选择该城市能获得的价值。

这样这个容量网络的S-T割,就能把首都划分到S集合要选择的划分到T集合二者分开,且其最小割就是最小的需要的耗费,耗费由摧毁边的费用和不选择某城市失去的价值组成,最大获利就是f个城市的价值和-最小割。

题目还要求最小割边集的割边,从源点floodfill得到的就是S集合的点,而所有一个端点在S集合另一端点在T集合的边就是最小割边集中的割边。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<queue>
  4. #include<algorithm>
  5. using namespace std;
  6. #define INF (1<<30)
  7. #define MAXN 1111
  8. #define MAXM 220000
  9.  
  10. struct Edge{
  11. int id,v,cap,flow,next;
  12. }edge[MAXM];
  13. int vs,vt,NE,NV;
  14. int head[MAXN];
  15.  
  16. void addEdge(int id,int u,int v,int cap){
  17. edge[NE].id=id; edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=;
  18. edge[NE].next=head[u]; head[u]=NE++;
  19. edge[NE].id=id; edge[NE].v=u; edge[NE].cap=; edge[NE].flow=;
  20. edge[NE].next=head[v]; head[v]=NE++;
  21. }
  22.  
  23. int level[MAXN];
  24. int gap[MAXN];
  25. void bfs(){
  26. memset(level,-,sizeof(level));
  27. memset(gap,,sizeof(gap));
  28. level[vt]=;
  29. gap[level[vt]]++;
  30. queue<int> que;
  31. que.push(vt);
  32. while(!que.empty()){
  33. int u=que.front(); que.pop();
  34. for(int i=head[u]; i!=-; i=edge[i].next){
  35. int v=edge[i].v;
  36. if(level[v]!=-) continue;
  37. level[v]=level[u]+;
  38. gap[level[v]]++;
  39. que.push(v);
  40. }
  41. }
  42. }
  43.  
  44. int pre[MAXN];
  45. int cur[MAXN];
  46. int ISAP(){
  47. bfs();
  48. memset(pre,-,sizeof(pre));
  49. memcpy(cur,head,sizeof(head));
  50. int u=pre[vs]=vs,flow=,aug=INF;
  51. gap[]=NV;
  52. while(level[vs]<NV){
  53. bool flag=false;
  54. for(int &i=cur[u]; i!=-; i=edge[i].next){
  55. int v=edge[i].v;
  56. if(edge[i].cap!=edge[i].flow && level[u]==level[v]+){
  57. flag=true;
  58. pre[v]=u;
  59. u=v;
  60. //aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
  61. aug=min(aug,edge[i].cap-edge[i].flow);
  62. if(v==vt){
  63. flow+=aug;
  64. for(u=pre[v]; v!=vs; v=u,u=pre[u]){
  65. edge[cur[u]].flow+=aug;
  66. edge[cur[u]^].flow-=aug;
  67. }
  68. //aug=-1;
  69. aug=INF;
  70. }
  71. break;
  72. }
  73. }
  74. if(flag) continue;
  75. int minlevel=NV;
  76. for(int i=head[u]; i!=-; i=edge[i].next){
  77. int v=edge[i].v;
  78. if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
  79. minlevel=level[v];
  80. cur[u]=i;
  81. }
  82. }
  83. if(--gap[level[u]]==) break;
  84. level[u]=minlevel+;
  85. gap[level[u]]++;
  86. u=pre[u];
  87. }
  88. return flow;
  89. }
  90.  
  91. bool vis[MAXN];
  92. void dfs(int u){
  93. vis[u]=;
  94. for(int i=head[u]; i!=-; i=edge[i].next){
  95. int v=edge[i].v;
  96. if(vis[v] || edge[i].cap==edge[i].flow) continue;
  97. dfs(v);
  98. }
  99. }
  100. int ans[];
  101. int main(){
  102. int t,n,m,f,a,b,c;
  103. scanf("%d",&t);
  104. for(int cse=; cse<=t; ++cse){
  105. scanf("%d%d%d",&n,&m,&f);
  106. vs=; vt=; NV=n+; NE=;
  107. memset(head,-,sizeof(head));
  108. for(int i=; i<=m; ++i){
  109. scanf("%d%d%d",&a,&b,&c);
  110. addEdge(i,a,b,c);
  111. }
  112. int tot=;
  113. while(f--){
  114. scanf("%d%d",&a,&b);
  115. tot+=b;
  116. addEdge(,a,vt,b);
  117. }
  118. printf("Case %d: %d\n",cse,tot-ISAP());
  119. memset(vis,,sizeof(vis));
  120. dfs(vs);
  121. tot=;
  122. for(int i=; i<NE; i+=){
  123. int u=edge[i^].v,v=edge[i].v;
  124. if(vis[u] && !vis[v] && edge[i].id) ans[tot++]=edge[i].id;
  125. }
  126. printf("%d",tot);
  127. for(int i=; i<tot; ++i) printf(" %d",ans[i]);
  128. putchar('\n');
  129. }
  130. return ;
  131. }

HDU3251 Being a Hero(最小割)的更多相关文章

  1. HDU 3251 Being a Hero(最小割+输出割边)

    Problem DescriptionYou are the hero who saved your country. As promised, the king will give you some ...

  2. HDU3251 最大流(最小割)

    Being a Hero Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...

  3. Being a Hero (hdu 3251 最小割 好题)

    Being a Hero Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  4. hdu3251 最小割

    题意: 给n个城市,m条有向边.每条边有权值,如今有些城市能够选择得到.可选的城市有一个价值.可是要满足从1到达不了这些城市,为了满足要求能够去掉一些边,须要花费边的权值,问终于得到的最大价值是多少, ...

  5. [HDU 3521] [最小割] Being a Hero

    题意: 在一个有向图中,有n个点,m条边$n \le 1000 \And \And  m \le 100000$ 每条边有一个破坏的花费,有些点可以被选择并获得对应的金币. 假设一个可以选的点是$x$ ...

  6. 最大流&最小割 - 专题练习

    [例1][hdu5889] - 算法结合(BFS+Dinic) 题意 \(N\)个点\(M\)条路径,每条路径长度为\(1\),敌人从\(M\)节点点要进攻\(1\)节点,敌人总是选择最优路径即最短路 ...

  7. BZOJ 1391: [Ceoi2008]order [最小割]

    1391: [Ceoi2008]order Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1509  Solved: 460[Submit][Statu ...

  8. BZOJ-2127-happiness(最小割)

    2127: happiness(题解) Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1806  Solved: 875 Description 高一 ...

  9. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

随机推荐

  1. Struts.xml讲解

    解决在断网环境下,配置文件无提示的问题我们可以看到Struts.xml在断网的情况下,前面有一个叹号,这时,我们按alt+/ 没有提示,这是因为” http://struts.apache.org/d ...

  2. 调用python 报R6034 错误

    R6034 指的是:"An application has made an attempt to load the C runtime library incorrectly. Please ...

  3. 反正切函数求圆周率 atan

    #define PI atan(1.0)*4 原理:tan ∏/4=1; atan2: 返回给定的 X 及 Y 坐标值的反正切值.反正切的角度值等于 X 轴正方向与通过原点和给定坐标点 (Y坐标, X ...

  4. MySQL 如何只导出 指定的表 的表结构和数据 ( 转 )

    MySQL 如何只导出 指定的表 的表结构和数据 ( 转 ) 2011-01-04 15:03:33 分类: MySQL MySQL 如何只导出 指定的表 的表结构和数据 导出更个库的表结构如下:my ...

  5. (转载)【Android】ViewGroup全面分析

    转载自:http://www.cnblogs.com/lqminn/archive/2013/01/23/2866543.html 一个Viewgroup基本的继承类格式如下: import andr ...

  6. Sublime Text 2 入门及技巧

    看了 Nettuts+ 对 Sublime Text 2 的介绍, 立刻就兴奋了,诚如作者 Jeffrey Way 所说:“<永远的毁灭公爵>都发布了,TextMate 2 还没发”,你还 ...

  7. linux安装setup工具

    如果你的Linux系统是最小化安装的,可能会没有setup命令工具,环境是centos 5.8 安装setup命令工具的步骤. 安装setuptool #yum install setuptool 系 ...

  8. 17.把字符串转换成整数[atoi]

    [题目] 把字符串转换成整数,需要考虑字符串有效性. [代码]  C++ Code  123456789101112131415161718192021222324252627282930313233 ...

  9. 惊魂web应用宕机记一次网站的紧急恢复

    这次网站的故障出现的比较突然,没有任何防备,有种突如其来的感觉.这是一台阿里云服务器,采用wdcp的nginx+apache+mysql的方式运行.一位同事在对web目录进行压缩后,由于web目录有很 ...

  10. WPF 将PPT,Word转成图片

    在Office下,PowerPoint可以直接把每张幻灯片转成图片,而Word不能直接保存图片.所以只能通过先转换成xps文件,然后再转成图片. 一.PPT 保存为图片 /// <summary ...