POJ - 3308 Paratroopers (最小点权覆盖)
题意:N*M个格点,K个位置会有敌人.每行每列都有一门炮,能打掉这一行(列)上所有的敌人.每门炮都有其使用价值.总花费是所有使用炮的权值的乘积.求最小的总花费.
若每门炮的权值都是1,就是求最小点覆盖的问题,参考:http://poj.org/problem?id=3041
将行视作X部,列视作Y部,敌人(i,j)视作连接点i和点N+j的边,要求一个点集合,使其能覆盖所有的边,且权值之积最小,即求最小点权覆盖.与求最大权独立集一样,也是用网络流求解.
这里处理积的方法是,将权值取对数,则log(a*b) = log(a) + log(b),转化为了加法运算.
建图步骤:建立源点s与汇点t.从源点s向X部的点建边,从Y部的点向汇点t建边,容量为其权值取对数.对敌人(i,j),由i向j+N建容量为正无穷的边.
跑出最大流即为其最小点权覆盖的值,最后pow计算出实际花费.
*其实带权的二分图,用网络流求最小点权覆盖与求最大独立集还是运用了二分图中的思想.二分图中,|最大独立集| = N - |最小点权覆盖| = N - |最大匹配|.
而在用网络流求解时,|最大流| = |最小割| = |最小点权覆盖|, |最大权独立集| = |总权值| - |最小点权覆盖| = |总权置| - |最大流|
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
const double INF = 100000.0;
const int MAXN=3010;//点数的最大值
const int MAXM=400010;//边数的最大值
#define captype double
struct SAP_MaxFlow{
struct Edge{
int from,to,next;
captype cap;
}edges[MAXM];
int tot,head[MAXN];
int gap[MAXN];
int dis[MAXN];
int cur[MAXN];
int pre[MAXN];
void init(){
tot=0;
memset(head,-1,sizeof(head));
}
void AddEdge(int u,int v,captype c,captype rc=0){
edges[tot] = (Edge){u,v,head[u],c}; head[u]=tot++;
edges[tot] = (Edge){v,u,head[v],rc}; head[v]=tot++;
}
captype maxFlow_sap(int sNode,int eNode, int n){//n是包括源点和汇点的总点个数,这个一定要注意
memset(gap,0,sizeof(gap));
memset(dis,0,sizeof(dis));
memcpy(cur,head,sizeof(head));
pre[sNode] = -1;
gap[0]=n;
captype ans=0;
int u=sNode;
while(dis[sNode]<n){
if(u==eNode){
captype Min=INF ;
int inser;
for(int i=pre[u]; i!=-1; i=pre[edges[i^1].to])
if(Min>edges[i].cap){
Min=edges[i].cap;
inser=i;
}
for(int i=pre[u]; i!=-1; i=pre[edges[i^1].to]){
edges[i].cap-=Min;
edges[i^1].cap+=Min;
}
ans+=Min;
u=edges[inser^1].to;
continue;
}
bool flag = false;
int v;
for(int i=cur[u]; i!=-1; i=edges[i].next){
v=edges[i].to;
if(edges[i].cap>0 && dis[u]==dis[v]+1){
flag=true;
cur[u]=pre[v]=i;
break;
}
}
if(flag){
u=v;
continue;
}
int Mind= n;
for(int i=head[u]; i!=-1; i=edges[i].next)
if(edges[i].cap>0 && Mind>dis[edges[i].to]){
Mind=dis[edges[i].to];
cur[u]=i;
}
gap[dis[u]]--;
if(gap[dis[u]]==0) return ans;
dis[u]=Mind+1;
gap[dis[u]]++;
if(u!=sNode) u=edges[pre[u]^1].to; //退一条边
}
return ans;
}
}F;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T; scanf("%d", &T);
double cap;
int u,v,tmp;
while(T--){
F.init();
int n,m,k; scanf("%d %d %d",&n, &m,&k);
int s = 0, t = n+m+1;
for(int i=1;i<=n;++i){
scanf("%lf", &cap);
F.AddEdge(s,i,log(cap));
}
for(int i=1;i<=m;++i){
scanf("%lf", &cap);
F.AddEdge(i+n,t,log(cap));
}
while(k--){
scanf("%d %d",&u,&v);
F.AddEdge(u,v+n,INF);
}
double res = exp(F.maxFlow_sap(s,t,t+1));
printf("%.4lf\n",res);
}
return 0;
}
POJ - 3308 Paratroopers (最小点权覆盖)的更多相关文章
- poj3308 Paratroopers --- 最小点权覆盖->最小割
题目是一个非常明显的二分图带权匹配模型, 加入源点到nx建边,ny到汇点建边,(nx.ny)=inf建边.求最小割既得最小点权覆盖. 在本题中因为求的是乘积,所以先所有取log转换为加法,最后再乘方回 ...
- POJ 3308 Paratroopers(最小割EK(邻接表&矩阵))
Description It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the ...
- zoj 2874 & poj 3308 Paratroopers (最小割)
意甲冠军: 一m*n该网络的规模格.详细地点称为伞兵着陆(行和列). 现在,在一排(或列) 安装激光枪,激光枪可以杀死线(或塔)所有伞兵.在第一i安装一排 费用是Ri.在第i列安装的费用是Ci. 要安 ...
- POJ 3308 Paratroopers(最小点权覆盖)(对数乘转加)
http://poj.org/problem?id=3308 r*c的地图 每一个大炮可以消灭一行一列的敌人 安装消灭第i行的大炮花费是ri 安装消灭第j行的大炮花费是ci 已知敌人坐标,同时消灭所有 ...
- POJ 3308 Paratroopers(最大流最小割の最小点权覆盖)
Description It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the ...
- poj 3308 Paratroopers(二分图最小点权覆盖)
Paratroopers Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8954 Accepted: 2702 Desc ...
- POJ 3308 Paratroopers (对数转换+最小点权覆盖)
题意 敌人侵略r*c的地图.为了消灭敌人,可以在某一行或者某一列安置超级大炮.每一个大炮可以瞬间消灭这一行(或者列)的敌人.安装消灭第i行的大炮消费是ri.安装消灭第j行的大炮消费是ci现在有n个敌人 ...
- poj 3308(最小点权覆盖、最小割)
题目链接:http://poj.org/problem?id=3308 思路:裸的最小点权覆盖,建立超级源点和超级汇点,将源点与行相连,容量为这行消灭敌人的代价,将列与汇点相连,容量为这列消灭敌人的代 ...
- poj 2125 Destroying The Graph (最小点权覆盖)
Destroying The Graph http://poj.org/problem?id=2125 Time Limit: 2000MS Memory Limit: 65536K ...
随机推荐
- Excel随机生成数据2
200万耗时大约 10秒以内,输出结果到txt文件. Sub GetPassword() 'by kagawa Dim i&, j&, k&, l&, m&, ...
- Gradle -- buildScript块与allprojects块及根级别的repositories区别
http://blog.sina.com.cn/s/blog_72ef7bea0102vvg3.html
- 使用JSP表达式和JSP脚本打印九九乘法表
首先使用JSP声明声明一个函数用于得到九九乘法表的内容 <%! String printMultiTable() { String s = ""; for (int i = ...
- spring基础---->spring自定义标签(一)
Spring具有一个基于架构的扩展机制,可以使用xml文件定义和配置bean.本博客将介绍如何编写自定义XML bean的解析器,并用实例来加以说明.其实我一直相信 等你出现的时候我就知道是你. Sp ...
- APNS/苹果推送服务
Apple Push Notification Service Google Cloud Message/Google 云 消息 Firebase Cloud Messaging
- Exchange OAB(Offline Address Book)
If Outlook is left running constantly in Cached Exchange Mode, it updates the Offline Address Book a ...
- Tilera--100核cpu
市场对多核的需求越来越多,主要是因为单核处理能力不可能像以往那样不断地提升.从上世纪90 年代开始,整个产业遵循摩尔定律,即芯片上可容纳的晶体管数目每隔18个月便会增加一倍,性能也提升一倍.随着时间的 ...
- 并发编程&数据库 - 考核题
第八章主要内容 第八章:线程.进程.队列.IO多路模型 操作系统工作原理介绍.线程.进程演化史.特点.区别.互斥锁.信号.事件.join.GIL.进程间通信.管道.队列. 生产者消息者模型.异步模型. ...
- d3.js 之关联数据:data操作符
数据可视化 在可视化工作中,一个基本出发点是将不同的数值映射到不同的可视化 元素的属性上,使其表现出各自不同的视觉特征. 比如:以数组中的每一个值为直径分别创建一个圆,我们得到三个圆: 在d3中,可视 ...
- python爬虫防止IP被封的一些措施
在编写爬虫爬取数据的时候,因为很多网站都有反爬虫措施,所以很容易被封IP,就不能继续爬了.在爬取大数据量的数据时更是瑟瑟发抖,时刻担心着下一秒IP可能就被封了. 本文就如何解决这个问题总结出一些应对措 ...