题目链接:http://poj.org/problem?id=3308

思路:裸的最小点权覆盖,建立超级源点和超级汇点,将源点与行相连,容量为这行消灭敌人的代价,将列与汇点相连,容量为这列消灭敌人的代价,对于每一个敌人(x,y),连边x->y,容量为inf,这样就说明选取的点覆盖了那些边(敌人),然后跑最大流求最小割即可。

PS:这里是乘积最小,要取对数转化为和最小。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
#define MAXN 222
#define MAXM 444444
#define inf 1<<30 struct Edge{
int v,next;
double cap;
}edge[MAXM]; int n,m,T,NE,NV,vs,vt;
int head[MAXN]; void Insert(int u,int v,double cap)
{
edge[NE].v=v;
edge[NE].cap=cap;
edge[NE].next=head[u];
head[u]=NE++; edge[NE].v=u;
edge[NE].cap=;
edge[NE].next=head[v];
head[v]=NE++;
} int level[MAXN],gap[MAXN];
void bfs(int vt)
{
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[vt]=;
gap[level[vt]]++;
queue<int>que;
que.push(vt);
while(!que.empty()){
int u=que.front();
que.pop();
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(level[v]<){
level[v]=level[u]+;
gap[level[v]]++;
que.push(v);
}
}
}
} int pre[MAXN],cur[MAXN];
double SAP(int vs,int vt)
{
bfs(vt);
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(head));
double maxflow=,aug=inf;
int u=pre[vs]=vs;
gap[]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap>&&level[u]==level[v]+){
flag=true;
pre[v]=u;
u=v;
aug=min(aug,edge[i].cap);
if(v==vt){
maxflow+=aug;
for(u=pre[v];v!=vs;v=u,u=pre[u]){
edge[cur[u]].cap-=aug;
edge[cur[u]^].cap+=aug;
}
aug=inf;
}
break;
}
}
if(flag)continue;
int minlevel=NV;
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap>&&level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==)break;
level[u]=minlevel+;
gap[level[u]]++;
u=pre[u];
}
return maxflow;
} int main()
{
double x,y;
int _case,u,v;
scanf("%d",&_case);
while(_case--){
scanf("%d%d%d",&n,&m,&T);
NE=;
memset(head,-,sizeof(head));
vs=,vt=n+m+,NV=vt+;
for(int i=;i<=n;i++){
scanf("%lf",&x);
Insert(vs,i,log(x));
}
for(int i=;i<=m;i++){
scanf("%lf",&y);
Insert(i+n,vt,log(y));
}
while(T--){
scanf("%d%d",&u,&v);
Insert(u,v+n,inf);
}
double ans=SAP(vs,vt);
printf("%.4f\n",exp(ans));
}
return ;
}

poj 3308(最小点权覆盖、最小割)的更多相关文章

  1. POJ2125 Destroying The Graph 二分图 + 最小点权覆盖 + 最小割

    思路来源:http://blog.csdn.net/lenleaves/article/details/7873441 求最小点权覆盖,同样求一个最小割,但是要求出割去了那些边, 只要用最终的剩余网络 ...

  2. POJ 3308 Paratroopers(最小点权覆盖)(对数乘转加)

    http://poj.org/problem?id=3308 r*c的地图 每一个大炮可以消灭一行一列的敌人 安装消灭第i行的大炮花费是ri 安装消灭第j行的大炮花费是ci 已知敌人坐标,同时消灭所有 ...

  3. POJ 3308 Paratroopers(最大流最小割の最小点权覆盖)

    Description It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the ...

  4. POJ - 3308 Paratroopers (最小点权覆盖)

    题意:N*M个格点,K个位置会有敌人.每行每列都有一门炮,能打掉这一行(列)上所有的敌人.每门炮都有其使用价值.总花费是所有使用炮的权值的乘积.求最小的总花费. 若每门炮的权值都是1,就是求最小点覆盖 ...

  5. POJ 2125 Destroying The Graph (二分图最小点权覆盖集+输出最小割方案)

    题意 有一个图, 两种操作,一种是删除某点的所有出边,一种是删除某点的所有入边,各个点的不同操作分别有一个花费,现在我们想把这个图的边都删除掉,需要的最小花费是多少. 思路 很明显的二分图最小点权覆盖 ...

  6. POJ 3308 Paratroopers (对数转换+最小点权覆盖)

    题意 敌人侵略r*c的地图.为了消灭敌人,可以在某一行或者某一列安置超级大炮.每一个大炮可以瞬间消灭这一行(或者列)的敌人.安装消灭第i行的大炮消费是ri.安装消灭第j行的大炮消费是ci现在有n个敌人 ...

  7. poj 3308 Paratroopers(二分图最小点权覆盖)

    Paratroopers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8954   Accepted: 2702 Desc ...

  8. poj 2125 Destroying The Graph (最小点权覆盖)

    Destroying The Graph http://poj.org/problem?id=2125 Time Limit: 2000MS   Memory Limit: 65536K       ...

  9. POJ 2125 Destroying the Graph 二分图最小点权覆盖

    Destroying The Graph Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8198   Accepted: 2 ...

随机推荐

  1. java写的小脚本,用来受mDNS消息

    太ugly了,但是可以工作,抓了包下来,用前面DNS message structure做了下比较. 代码如下: import java.net.DatagramPacket; import java ...

  2. tableView 获取网络图片,并且设置为圆角(优化,fps)

    代码地址如下:http://www.demodashi.com/demo/11088.html 一.准备工作 例子比较精简,没有什么特殊要求,具备Xocde8.0左右版本的就好 二.程序实现 1.相关 ...

  3. easyui 动态加载语言包

    解决办法是:把语言包中的语言类型写到cookie,动态修改cookie中的语言名称,修改完后重新渲染一下页面. 在页面加载完成后,先判断cookie存不存在,如果不存在就写入默认语言,存在就给easy ...

  4. AMQP && MQTT comparision

    1. AMQP (Advanced Message Queuing Protocol) 2. MQTT (Message Queuing Telemetry Transport) Introducti ...

  5. python selenium --调用js

    转自:http://www.cnblogs.com/fnng/p/3230768.html 本节重点: 调用js方法 execute_script(script, *args) 在当前窗口/框架 同步 ...

  6. json再理解

    一.Json的简单介绍 从结构上看,所有的数据最终都可以分成三种类型: 第一种类型是scalar(标量),也就是一个单独的string(字符串)或数字(numbers),比如“北京”这个单独的词. 第 ...

  7. VS2015 经常不出现智能提示,代码颜色也没有了

    重置下.开始菜单 -->所有程序-->Visual Studio 文件夹 --> Visual Studio Tools --> Developer Command Promp ...

  8. 使用 GROUP BY WITH ROLLUP 改善统计性能

    使用 GROUP BY 的 WITH ROLLUP 字句可以检索出更多的分组聚合信息,它不仅仅能像一般的 GROUP BY 语句那样检索出各组的聚合信息,还能检索出本组类的整体聚合信息. 下面我们的例 ...

  9. 点滴积累【C#】---序列化和反序列化

    序列化和反序列化效果图: 序列化和反序列化代码: 需要添加两个命名空间: using System.IO; using System.Runtime.Serialization.Formatters. ...

  10. matplotlib 添加注释的方式

    matplotlib 添加注释的方式 matplotlib.pyplot.annotate Annotate the point xy with text s s : str The text of ...