poj3308Paratroopers(最小割)
题目大意:给一个n*m的矩阵,给一些点(ri,ci)表示该点在第ri行第ci列。现在要覆盖所有的点,已知覆盖第i行代价为Ri,覆盖第j列代价为Cj。总代价是累乘的,求最小总代价能覆盖所有的点。
题目分析:最小割。增加一个超级源点和超级汇点,源点到行连边,边权为覆盖行的代价,每列到汇点建边,边权为覆盖该列的代价。对于给定的点对,ri->cj连边,边权无穷大。求一个最小割即可。因为根据割的性质,会将图分成2部分,一部分含源点,一部分含汇点,那么这个割集的边只可能为s->ri、ri->cj、cj->t中的某些边,而ri->cj权是无穷大的,所以不会选这些边,因此割集必在s->ri和cj->t中,那么割集中的边就代表选中要覆盖的行和列,因为要总代价最小,所以求出最小割就是最小总代价。
因为总代价是累乘的,所以要化乘法为加法,取对数。
trick:输出浮点数的时候%.f,%.lf会WA。。。
详情请见代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 105;
const int M = 5500;
const double inf = 100000000.0;
const double eps = 1e-8;
int m,n,l,num;
struct node
{
double c;
int to,next,pre;
}arc[M];
int head[N],sta[N],que[N],cnt[N],dis[N],rpath[N];
void build(int s,int e,double cap)
{
arc[num].to = e;
arc[num].c = cap;
arc[num].next = head[s];
head[s] = num ++;
arc[num - 1].pre = num;
arc[num].pre = num - 1;
arc[num].to = s;
arc[num].c = 0.0;
arc[num].next = head[e];
head[e] = num ++;
}
void re_Bfs()
{
int i,front,rear;
for(i = 0;i <= n + m + 1;i ++)
{
dis[i] = n + m + 2;
cnt[i] = 0;
}
front = rear = 0;
dis[n + m + 1] = 0;
cnt[0] = 1;
que[rear ++] = n + m + 1;
while(front != rear)
{
int u = que[front ++];
for(i = head[u];i != -1;i = arc[i].next)
{
if(arc[arc[i].pre].c < eps || dis[arc[i].to] < n + m + 2)
continue;
dis[arc[i].to] = dis[u] + 1;
cnt[dis[arc[i].to]] ++;
que[rear ++] = arc[i].to;
}
}
}
void ISAP()
{
re_Bfs();
int i,u;
double maxflow = 0.0;
for(i = 0;i <= n + m + 1;i ++)
sta[i] = head[i];
u = 0;
while(dis[0] < n + m + 2)
{
if(u == n + m + 1)
{
double curflow = inf;
for(i = 0;i != m + n + 1;i = arc[sta[i]].to)
curflow = min(curflow,arc[sta[i]].c);
for(i = 0;i != m + n + 1;i = arc[sta[i]].to)
{
arc[sta[i]].c = arc[sta[i]].c - curflow;
arc[arc[sta[i]].pre].c = arc[arc[sta[i]].pre].c + curflow;
}
maxflow = maxflow + curflow;
u = 0;
}
for(i = sta[u];i != -1;i = arc[i].next)
if(arc[i].c > eps && dis[arc[i].to] + 1 == dis[u])
break;
if(i != -1)
{
sta[u] = i;
rpath[arc[i].to] = arc[i].pre;
u = arc[i].to;
}
else
{
if((-- cnt[dis[u]]) == 0)
break;
sta[u] = head[u];
int Min = m + n + 2;
for(i = sta[u];i != -1;i = arc[i].next)
if(arc[i].c > eps)
Min = min(Min,dis[arc[i].to]);
dis[u] = Min + 1;
cnt[dis[u]] ++;
if(u != 0)
u = arc[rpath[u]].to;
}
}
printf("%.4lf\n",pow(10.0,maxflow));
}
int main()
{
int t,i;
int a,b;
double x;
scanf("%d",&t);
while(t --)
{
memset(head,-1,sizeof(head));
scanf("%d%d%d",&n,&m,&l);
for(i = 1;i <= n;i ++)
{
scanf("%lf",&x);
build(0,i,log10(x));
}
for(i = 1;i <= m;i ++)
{
scanf("%lf",&x);
build(n + i,m + n + 1,log10(x));
}
while(l --)
{
scanf("%d%d",&a,&b);
build(a,n + b,inf);
}
ISAP();
}
return 0;
}
//568K 16MS
poj3308Paratroopers(最小割)的更多相关文章
- BZOJ 1391: [Ceoi2008]order [最小割]
1391: [Ceoi2008]order Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1509 Solved: 460[Submit][Statu ...
- BZOJ-2127-happiness(最小割)
2127: happiness(题解) Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1806 Solved: 875 Description 高一 ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- BZOJ3438 小M的作物(最小割)
题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=3438 Description 小M在MC里开辟了两块巨大的耕地A和B(你可以认为 ...
- 最大流-最小割 MAXFLOW-MINCUT ISAP
简单的叙述就不必了. 对于一个图,我们要找最大流,对于基于增广路径的算法,首先必须要建立反向边. 反向边的正确性: 我努力查找了许多资料,都没有找到理论上关于反向边正确性的证明. 但事实上,我们不难理 ...
- bzoj1412最小割
太羞耻了,m n写反了(主要是样例n m相等) 建图方法比较高(ji)端(chu),对于可以加栅栏的地方连上1的边,然后求最小割即可 为了让代码优(suo)美(duan),我写了一个check,避免多 ...
- 【BZOJ1497】[NOI2006]最大获利 最小割
裸的最小割,很经典的模型. 建图:要求总收益-总成本最大,那么将每条弧与源点相连,流量为成本,每个收益与汇点相连,流量为收益,然后每条弧与它所能到达的收益相连,流量为inf. 与源点相连的是未被选中的 ...
- 二分图&网络流&最小割等问题的总结
二分图基础: 最大匹配:匈牙利算法 最小点覆盖=最大匹配 最小边覆盖=总节点数-最大匹配 最大独立集=点数-最大匹配 网络流: 技巧: 1.拆点为边,即一个点有限制,可将其转化为边 BZOJ1066, ...
- CQOI 2016 不同的最小割
题目大意:一个无向图,求所有点对不同的最小割种类数 最小割最多有n-1个,这n-1个最小割构成一个最小割树 分治法寻找n-1个最小割.对于当前点集X,任选两点为ST做最小割,然后找出与S相连的所有点和 ...
随机推荐
- BootStrap 智能表单系列 十一 级联下拉的支持
像省市县选择的这种,但凡是个人肯定都见过,实现方式有很多种 1.有在第一级选择的时候去加载或者从本地对象中拿第一级对应的数据源显示到列表中,第二级以此类推 2.也有将所有的项都加载到select中,然 ...
- iOS面试题01-多线程网络
1.面试题方向: 1>.多线程+网络 2>.项目(简历上的项目,每一个细节:技术实现细节.业务.项目周期.人数) 3>.性能优化:图片优化.内存优化(tableView的循环利用) ...
- untiy 播放视频
利用 MovieTexture 类 放入视频 视频不能使flv的 建立一个平面 作为屏幕,利用Material 播放动画,剩下的就是将平面放大和屏幕一样/ public MovieTexture My ...
- C#中linq报“Character literal must contain exactly one character”的错误提示
后台代码使用linq提示"Character literal must contain exactly one character": 网上看了一下提示在部分linq语句中直接写入 ...
- 关于一个wpf中的定时器
http://www.cnblogs.com/royenhome/archive/2010/01/24/1655168.html
- php基础知识(很简单一套适合零基础的朋友学习)
红色的一般都是重点,还有自己的一些废话 运算符 算术运算符: 基本运算(除数不能为0) 比较运算符: 大小比较(类型比较), 如果两个类型不一样,系统会自动转换成统一类型 赋值运算符: 基本赋值和运算 ...
- 高性能javascript 学习笔记(1)
加载和运行 管理浏览器中的javascript代码是个棘手的问题,因为代码运行阻塞了其他浏览器处理过程,诸如用户绘制,每次遇到<script>标签,页面必须停下来等待代码下载(如果是外部的 ...
- python的filter()函数
filter()函数是 Python 内置的另一个有用的高阶函数. filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,fil ...
- (Problem 74)Digit factorial chains
The number 145 is well known for the property that the sum of the factorial of its digits is equal t ...
- CentOS 6.4下Squid代理服务器的安装与配置,反向代理
CentOS 6.4下Squid代理服务器的安装与配置 一.简介 代理服务器英文全称是Proxy Server,其功能就是代理网络用户去取得网络信息. Squid是一个缓存Internet 数据的软件 ...