把入侵者看作边,每一行每一列都是点,选取某一行某一列都有费用,这样问题就是选总权最小的点集覆盖所有边,就是最小点权覆盖。

此外,题目的总花费是所有费用的乘积,这时有个技巧,就是取对数,把乘法变为加法运算,最后再还原。

另外还可以从最小割的思路去这么理解:

每一行与源点相连,容量为该行的花费;每一列与汇点相连,容量为该列的花费;对于每个入侵者的坐标,该行该列连接一条容量INF的边。

要让源点汇点不连通,割边集必然与所有入侵者的行或列相关,而这样建模后的最小割就是最小的花费(容量INF的边必然不是最小割的一部分,其余的必然会选择某行或某列)。

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

POJ3308 Paratroopers(最小割/二分图最小点权覆盖)的更多相关文章

  1. 【最小割/二分图最大独立集】【网络流24题】【P2774】 方格取数问题

    Description 给定一个 \(n~\times~m\) 的矩阵,每个位置有一个正整数,选择一些互不相邻的数,最大化权值和 Limitation \(1~\leq~n,~m~\leq~100\) ...

  2. ZOJ 3792 Romantic Value 最小割(最小费用下最小边数)

    求最小割及最小花费 把边权c = c*10000+1 然后跑一个最小割,则flow / 10000就是费用 flow%10000就是边数. 且是边数最少的情况.. #include<stdio. ...

  3. bzoj2229: [Zjoi2011]最小割(分治最小割+最小割树思想)

    2229: [Zjoi2011]最小割 题目:传送门 题解: 一道非常好的题目啊!!! 蒟蒻的想法:暴力枚举点对跑最小割记录...绝对爆炸啊.... 开始怀疑是不是题目骗人...难道根本不用网络流?? ...

  4. BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan

    BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan Description A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤ ...

  5. HDU 4859 海岸线(最小割+最大独立点权变形)

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题意: 欢迎来到珠海!由于土地资源越来越紧张,使得许多海滨城市都只能依靠填海来扩展市区以求发展.作为Z市的 ...

  6. [学习笔记]最小割之最小点权覆盖&&最大点权独立集

    最小点权覆盖 给出一个二分图,每个点有一个非负点权 要求选出一些点构成一个覆盖,问点权最小是多少 建模: S到左部点,容量为点权 右部点到T,容量为点权 左部点到右部点的边,容量inf 求最小割即可. ...

  7. BZOJ 1934 Vote 善意的投票(最小割+二分图)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1934 题目大意: 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题 ...

  8. bzoj1001/luogu4001 狼抓兔子 (最小割/平面图最小割转对偶图最短路)

    平面图转对偶图:先在原图中加一个s->t的边,然后对每个面建一个点,对每条分隔两个面的边加一条连接这两个面对应点的边,边权等于原边权. 然后从刚才加的s->t分割出来的两面对应的两个点跑最 ...

  9. bzoj4519: [Cqoi2016]不同的最小割(最小割树)

    传送门 好神仙……最小割树是个什么东西…… 其实我觉得干脆直接$O(n^2)$跑几个dinic算了…… 来说一下这个叫最小割树的神奇东西 我们先建一个$n$个点,没有边的无向图 在原图中任选两点$s, ...

随机推荐

  1. [Android Pro] 使用apktool工具遇到could not decode arsc file的解决办法

    转:http://www.cnblogs.com/sage-blog/p/4323049.html 最近使用APKtool工具反编译APK老是提示不成功,错误如下: Exception in thre ...

  2. !对c++类的理解

    c++的类可以分为两类,一种是entity的类(i.e.,实体类),一种是function的类(i.e.,功能类). 对于构造entity的类,包括这种entity的属性已经它本身具备的功能: 而fu ...

  3. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(二) 之 ChatServer搭建,连接服务器,以及注意事项。

    上篇:ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取) 上一篇我们已经完成了初步界面的搭建工作,本篇将介绍IM的核心内容 ...

  4. python处理html的table标签

    转载:http://www.xuebuyuan.com/583071.html python处理html的table标签 2012年01月06日 ⁄ 综合 ⁄ 共 5279字 ⁄ 字号 小 中 大 ⁄ ...

  5. 浅析 - Storyboard / Xib

    大家都知道纯代码写应用的成本是很高的,特别是涉及到UI界面的实现,相当耗费时间.之前自己写应用时有了解过Storyboard,也简单使用过,但随着最近深入了解它之后,发现自己低估了它的作用和影响力,因 ...

  6. Swift - 文件目录路径获取及数据储存(Home目录,文档目录,缓存目录)

    iOS应用程序只能在自己的目录下进行文件的操作,不可以访问其他的存储空间,此区域被称为沙盒.   应用沙盒结构分析 1.应用程序包:包含了所有的资源文件和可执行文件 2.Documents:保存应用运 ...

  7. myeclipse相关

    :) MyEclipse 10.7以后开始支持JDK1.7,修改settings下面的配置文件没卵用.

  8. 使用Delphi对象(声明、实例化、构造、释放)

    一.声明和实例化 在使用一个对象之前,用class关键字声明一个对象.可以在一个程序或单元的type部分声明一个对象类型: type TFooObject = class; 除了声明一个对象类型,通常 ...

  9. centos(x86 64位系统)使用boost

    1. 安装gcc,g++,make等开发环境 yum groupinstall "Development Tools" 2. 安装boost yum install boost b ...

  10. wp8 入门到精通 MultiMsgPrompt

    List<NotifyMsg> arraymsg = new List<NotifyMsg>(); List<NotifyInfo> ArrayNotifyInfo ...