【第21期】观点:人工智能到底用 GPU?还是用 FPGA?

POJ 3308 Paratroopers 最小点权覆盖Dinic

原创 2015年11月20日 23:28:21
F - Paratroopers
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the Mars. Recently, the commanders of the Earth are informed by their spies that the invaders of Mars want to land some paratroopers in the × n grid yard of one their main weapon factories in order to destroy it. In addition, the spies informed them the row and column of the places in the yard in which each paratrooper will land. Since the paratroopers are very strong and well-organized, even one of them, if survived, can complete the mission and destroy the whole factory. As a result, the defense force of the Earth must kill all of them simultaneously after their landing.

In order to accomplish this task, the defense force wants to utilize some of their most hi-tech laser guns. They can install a gun on a row (resp. column) and by firing this gun all paratroopers landed in this row (resp. column) will die. The cost of installing a gun in the ith row (resp. column) of the grid yard is ri (resp. ci ) and the total cost of constructing a system firing all guns simultaneously is equal to the product of their costs. Now, your team as a high rank defense group must select the guns that can kill all paratroopers and yield minimum total cost of constructing the firing system.

Input

Input begins with a number T showing the number of test cases and then, T test cases follow. Each test case begins with a line containing three integers 1 ≤ m ≤ 50 , 1 ≤ n ≤ 50 and 1 ≤ l ≤ 500 showing the number of rows and columns of the yard and the number of paratroopers respectively. After that, a line with m positive real numbers greater or equal to 1.0 comes where the ith number is ri and then, a line with npositive real numbers greater or equal to 1.0 comes where the ith number is ci. Finally, l lines come each containing the row and column of a paratrooper.

Output

For each test case, your program must output the minimum total cost of constructing the firing system rounded to four digits after the fraction point.

Sample Input

1
4 4 5
2.0 7.0 5.0 2.0
1.5 2.0 2.0 8.0
1 1
2 2
3 3
4 4
1 4

Sample Output

16.0000

火星人进攻地球在n*m的格子内部,地球人可以在n行每一行安装枪,m列同理。在不同地方安放枪费用不同,问如何安放使得行花费乘上列花费最小使得消灭所有敌人。

这就是最小点集覆盖,最小割用dinic模板。因为是求乘所以转为对数就变成了加法。

ACcode:

#pragma warning(disable:4786)//使命名长度不受限制
#pragma comment(linker, "/STACK:102400000,102400000")//手工开栈
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <stack>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
#define rds(x) scanf("%s",x)
#define rdc(x) scanf("%c",&x)
#define ll long long int
#define maxn 100005
#define mod 1000000007
#define INF 1e8 //int 最大值
#define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;++i)
#define MT(x,i) memset(x,i,sizeof(x))
#define PI  acos(-1.0)
#define E  exp(1)
#define esp 0.00000001
using namespace std;
struct Edge{
    int to,next;
    double w;
}e[maxn];
int n,m,loop,num,tot,head[maxn],level[maxn];
void addEdge(int u,int v,double w){
    e[tot].to=v;e[tot].w=w;e[tot].next=head[u];head[u]=tot++;
    e[tot].to=u;e[tot].w=0;e[tot].next=head[v];head[v]=tot++;
}
bool makelevel(){
    double w;
    MT(level,-1);
    int que[maxn];
    int front=0,rear=0,u;
    level[rear++]=0;
    while(front!=rear){
        u=que[front++];
        for(int k=head[u];k!=-1;k=e[k].next){
            int v=e[k].to;
            w=e[k].w;
            if(w>esp&&level[v]<0){
                level[v]=level[u]+1;
                que[rear++]=v;
            }
        }
    }
    return level[n+m+1]>=0;
}
double dfs(int now ,double maxf,int t){
    if(now==t)return maxf;
    double ret=0,s;
    for(int k=head[now];k!=-1;k=e[k].next){
            int v=e[k].to;
            double w=e[k].w;
            if(w>esp&&level[v]==level[now]+1&&(s=dfs(v,min(maxf,w),t))){
                e[k].w-=s;
                e[k^1].w+=s;
                return s;
            }
        }
    return 0;
}
double dinic(int s,int t){
    double ans=0,ss;
    while(makelevel()){
            ss=dfs(s,INF,t);
        if(ss>esp)
            ans+=ss;
        else break;
    }
    return ans;
}
int main(){
    rd(loop);
    while(loop--){
        double val;
        int u,v;
        MT(head,-1);
        tot=0;
        rd2(n,m);rd(num);
        FOR(i,1,n){
            scanf("%lf",&val);
            addEdge(0,i,log(val));
        }
        FOR(i,1,m){
            scanf("%lf",&val);
            addEdge(n+i,n+m+1,log(val));
        }
        FOR(i,1,num){
            rd2(u,v);
            addEdge(u,v+n,INF);
        }
        printf("%0.4lf\n",exp(dinic(0,n+m+1)));
    }
    return 0;
}
/*
1
4 4 5
2.0 7.0 5.0 2.0
1.5 2.0 2.0 8.0
1 1
2 2
3 3
4 4
1 4
*/



版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

POJ 1325 Machine Schedule 最小点覆盖

机器A的所有模式为左部顶点,机器B的所有模式为右部顶点,然后A与B之间的每条连线代表一个任务或工作 之后就要完成所有的任务,即将每条边都覆盖 <span style="font-family: Arial; font-size: 14px; line-h

poj_3308 Paratroopers(二分图最小点权覆盖集+dinic+化乘为加)

Paratroopers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8514   Accepted: 257...

POJ 2226 二分图 最小点覆盖

这题的建图比较神 首先要明白题意是要覆盖所有的污泥,而不能把草地也给覆盖了 刚开始我就把草地也给覆盖了,显然不行。 那么就需要划分为一个一个的线段来进行覆盖 将所有横着的线段分别预处理出来,每个线段给一个编号 同样所有竖着的线段预处理出来。注意只要是连续的几个污泥块就属于同一个线段,横着的和竖着的分别处理。 然后对每个污泥,用其所属的横线段的编号跟所属的竖线段的编号连边。 最后转化为最小点覆盖模型。 <pre name="code" class="cp

图论练习题

图论练习题标签(空格分隔): ACM 图论 综合第一部分:最短路1.poj1062 昂贵的聘礼(中等) 此题是个经典题目;用Dijkstra即可;但是其中的等级处理需要一定的技巧; ...

POJ 3308 二分图最小点权覆盖 最大流

本题题意就是,公元XXXX年,地球跟外星人打仗,然后有一个n*m的网格,会有外星人降落到某些位置上,因为外星人比较猛,所以必须一下来就消灭他们,现在可以在某些行或者某些列的首部放一些激光枪。这些枪的特性就是你放在行的首部你就消灭这一行的敌人,放在列的首部就消灭一列的敌人。但是放置这些枪也需要一定的费用,这些费用已经给出来了,最后总费用是这些枪的费用之积,现在要求最小的这个费用。 看到积之后,我们可以转换为加法,就是取log,但是不知道数据是什么情况,会不会超过double,就试一下。 然后就能发现是一个二分图最小点权覆盖的模型了 然后就是建
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)