zoj 2874 & poj 3308 Paratroopers (最小割)
意甲冠军:
一m*n该网络的规模格。详细地点称为伞兵着陆(行和列)。
现在,在一排(或列)
安装激光枪,激光枪可以杀死线(或塔)所有伞兵。在第一i安装一排
费用是Ri。在第i列安装的费用是Ci。
要安装整个激光枪系统,总费用为这些
激光枪费用的乘积。
求杀死全部伞兵的最小费用。
构图:
把伞兵视为边,行与列视为顶点。添加源点和汇点,对于第i行。从源点向顶点i连接一条
容量为Ri的边。对于第j列。从顶点j向汇点连接一条容量为Rj的边。
假设某一点(i,j)有伞兵降落,则从顶点Ri向顶点Cj连接一条容量为无穷大的边。
算法:
依据割的性质,源点和汇点必不连通。则割边必然在S->R,R->C,C->T其一。
为了求得最小容量,
将R->C设为无穷大,则其不可能被选中。这样割边集为S-->R,C-->T的集合,也就是选中行或列。
此时求得的最小割为花费最小的方案。
因为花费为行和列的乘积。则通过对数运算把乘法转化为加法。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#define maxm 15000
#define maxn 105
#define eps 1e-6
using namespace std; struct node
{
int v,next;
double val;
}e[maxm<<1];
int st,en,n,m,l,cnt;
int d[maxn];
int head[maxn],cur[maxn];
const double INF = 1000007;
queue<int> q; void init()
{
st = 0,en = n+m+1;
memset(head,-1,sizeof(head));
cnt = 0;
}
void add(int x,int y,double z)
{
e[cnt].v = y;
e[cnt].val = z;
e[cnt].next = head[x];
head[x]=cnt++;
e[cnt].v = x;
e[cnt].val = 0;
e[cnt].next = head[y];
head[y]=cnt++;
}
bool bfs()
{
while(!q.empty())
q.pop();
memset(d,-1,sizeof(d));
int u;
d[st] = 0;
q.push(st);
while(!q.empty())
{
u = q.front();
q.pop();
for(int i=head[u];i!=-1;i=e[i].next)
{
int t = e[i].v;
if(e[i].val>0 && d[t]==-1)
{
d[t] = d[u]+1;
q.push(t);
if(t==en) return true;
}
}
}
return false;
} double dfs(int x,double flow)
{
if(x==en || fabs(flow)<=eps) return flow;
double ret = 0,dd;
for(int& i=cur[x];i!=-1;i=e[i].next)
{
int t = e[i].v;
if(d[t] == d[x]+1 && (dd = dfs(t,min(flow,e[i].val)))>0)
{
e[i].val-=dd;
e[i^1].val+=dd;
flow-=dd;
ret+=dd;
if (fabs(flow) <= eps) break;
}
}
return ret;
}
double Dinic()
{
double tmp = 0,maxflow = 0;
while(bfs())
{
for(int i=0;i<=en;i++)
cur[i] = head[i];
maxflow+=dfs(st,INF);
}
return maxflow;
} int main()
{
int T,a,b;
double x;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&m,&n,&l);
init();
for(int i=1;i<=m;i++)
{
scanf("%lf",&x);
add(st,i,log(x));
}
for(int i=1;i<=n;i++)
{
scanf("%lf",&x);
add(i+m,en,log(x));
}
for(int i=1;i<=l;i++)
{
scanf("%d%d",&a,&b);
add(a,b+m,INF);
}
printf("%.4f\n",exp(Dinic()));
}
return 0;
}
版权声明:本文博主原创文章。博客,未经同意不得转载。
zoj 2874 & poj 3308 Paratroopers (最小割)的更多相关文章
- 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 ...
- POJ - 3308 Paratroopers (最小点权覆盖)
题意:N*M个格点,K个位置会有敌人.每行每列都有一门炮,能打掉这一行(列)上所有的敌人.每门炮都有其使用价值.总花费是所有使用炮的权值的乘积.求最小的总花费. 若每门炮的权值都是1,就是求最小点覆盖 ...
- POJ - 3308 Paratroopers(最大流)
1.这道题学了个单词,product 还有 乘积 的意思.. 题意就是在一个 m*n的矩阵中,放入L个敌军的伞兵,而我军要在伞兵落地的瞬间将其消灭.现在我军用一种激光枪组建一个防御系统,这种枪可以安装 ...
- 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(最小点权覆盖)(对数乘转加)
http://poj.org/problem?id=3308 r*c的地图 每一个大炮可以消灭一行一列的敌人 安装消灭第i行的大炮花费是ri 安装消灭第j行的大炮花费是ci 已知敌人坐标,同时消灭所有 ...
- POJ 3308 Paratroopers (对数转换+最小点权覆盖)
题意 敌人侵略r*c的地图.为了消灭敌人,可以在某一行或者某一列安置超级大炮.每一个大炮可以瞬间消灭这一行(或者列)的敌人.安装消灭第i行的大炮消费是ri.安装消灭第j行的大炮消费是ci现在有n个敌人 ...
- Paratroopers(最小割模型)
http://poj.org/problem?id=3308 题意:一个m*n的网格,有L位火星空降兵降落在网格中,地球卫士为了能同时消灭他们,在网格的行或列安装了一个枪支,每行或每列的枪支都能消灭这 ...
- poj 3084(最小割)
题目链接:http://poj.org/problem?id=3084 思路:题目的意思是不让入侵者进入保护的房间,至少需要锁几道门.网络流建模:设一个超级源点,源点与有入侵者的房间相连,边容量为in ...
- poj 1815(最小割、割集)
题目链接:http://poj.org/problem?id=1815 思路:题目要求是剔除多少个点,可以将其转化为剔除多少条边,因此需要拆点,将点i拆成i,i+n,便容量为1,表示每个人起的传递作用 ...
随机推荐
- ORACLE—005:创建JOB(二)
假设须要创建带參数的job,怎样创建呢. 我们直接将參数声明.并赋值.然后传给job调用的存储过程就可以. 比如.存储过程名为Pro_Test_JOB,參数共同拥有一个.是VARCHAR2类型. 创建 ...
- C语言复合字面量的使用
C99添加的特性,复合字面量(composite literal).一旦熟悉并使用,便会体会到简洁强大的表达. 所谓字面量就是固定数值的表示.数值和字符串类型都有字面量的表达.如: // 100, 1 ...
- 字符串string和内存流MemoryStream及比特数组byte[]互转
原文:字符串string和内存流MemoryStream及比特数组byte[]互转 字符串string和内存流MemoryStream及比特数组byte[]互转比较 定义string变量为str, ...
- Ajenti 1.0 发布,服务器管理系统 - 开源中国社区
Ajenti 1.0 发布,服务器管理系统 - 开源中国社区 Ajenti 1.0 发布,服务器管理系统
- Thrift反序列化导致OOM(转)
概述 最近线上的日志处理服务偶尔会出现Out Of Memory的问题,从Exception的call stack中顺藤摸瓜,最终定位到是thrift反序列化的问题. 发现问题 先交代一下问题现场: ...
- java泛型 之 入门(interface)
一:泛型简单介绍: (1)所谓泛型,就是变量类型的參数化. 泛型是JDK1.5中一个最重要的特征.通过引入泛型,我们将获得编译时类型的安全和执行时更小的抛出ClassCastException的可能. ...
- linux的tr命令
tr(translate缩写)主要用于删除文件中的控制字符,或进行字符转换. 语法 tr [ -c | -cds | -cs | -C | -Cds | -Cs | -ds | -s] [ -A] S ...
- js:进一步关闭(范围:下一个)
function fn1(){ //创建一个数组 var fns = new Array(); //i这个变量是保存在fn1这个作用域中 for(var i=0;i<10;i++ ...
- 【转向Javascript系列】从setTimeout说事件循环模型
本文首发在alloyteam团队博客,链接地址http://www.alloyteam.com/2015/10/turning-to-javascript-series-from-settimeout ...
- c++设计模式15 --组合模式
今天研究了一下设计模式15 组合模式 本人是菜鸟一枚,所以一开始完全不懂组合究竟是什么意思.先上图一张,树形结构图: 文档说,如果想做出这样的结构,通常考虑组合模式.那是为什么呢?现在让我们看一下组合 ...