POJ 3308 Paratroopers 最小点权覆盖 求最小割

不懂这个建模是什么原理,以后把二分图相关的东西看完再补上把= =

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>

using namespace std;

typedef long long LL;
const int maxn = 105;
const double INF = 1e60;
const double eps = 1e-9;
int level[maxn],n,m,c,q[maxn],qs,qe;
double cap[maxn][maxn];
int s,t;

bool bfs() {
    qs = qe = 0;
    memset(level,0,sizeof(level));
    level[s] = 1;
    q[qe++] = s;
    while(qs < qe) {
        int now = q[qs++];
        if(now == t) break;
        for(int i = s;i <= t;i++) if(cap[now][i] >= eps) {
            if(level[i] == 0) {
                q[qe++] = i; level[i] = level[now] + 1;
            }
        }
    }
    return level[t];
}

double dfs(int now,double alpha) {
    if(now == t) return alpha;
    double sum = 0;
    for(int i = s;i <= t && alpha >= eps;i++) {
        if(cap[now][i] >= eps && level[i] == level[now] + 1) {
            double ret = dfs(i,min(alpha,cap[now][i]));
            sum += ret; alpha -= ret;
            cap[now][i] -= ret; cap[i][now] += ret;
        }
    }
    if(sum < eps) level[now] = -1;
    return sum;
}

void solve() {
    double ans = 0;
    while(bfs()) ans += dfs(s,INF);
    printf("%.4f\n",exp(ans));
}

int main() {
    int T; scanf("%d",&T);
    while(T--) {
        memset(cap,0,sizeof(cap));
        scanf("%d%d%d",&n,&m,&c);
        s = 0; t = n + m + 1;
        for(int i = 1;i <= n;i++) {
            double tmp; scanf("%lf",&tmp);
            cap[s][i] = log(tmp);
        }
        for(int i = 1;i <= m;i++) {
            double tmp; scanf("%lf",&tmp);
            cap[i + n][t] = log(tmp);
        }
        for(int i = 1;i <= c;i++) {
            int a,b; scanf("%d%d",&a,&b);
            cap[a][b + n] = INF;
        }
        solve();
    }
    return 0;
}

  

POJ 3308 Paratroopers 最小点权覆盖 求最小割

时间: 2024-10-31 10:08:00

POJ 3308 Paratroopers 最小点权覆盖 求最小割的相关文章

poj3308 Paratroopers --- 最小点权覆盖-&amp;gt;最小割

题目是一个非常明显的二分图带权匹配模型, 加入源点到nx建边,ny到汇点建边,(nx.ny)=inf建边.求最小割既得最小点权覆盖. 在本题中因为求的是乘积,所以先所有取log转换为加法,最后再乘方回来. #include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #in

POJ 2125 --Destroying The Graph【最小割解决 &quot;最小点权覆盖问题&quot; &amp;&amp; 输出解(割边集) &amp;&amp; 各种不懂】

Destroying The Graph Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7597   Accepted: 2434   Special Judge Description Alice and Bob play the following game. First, Alice draws some directed graph with N vertices and M arcs. After that B

HLG1407Leyni的游戏【最小点权覆盖集】

大意: 给你一个n行m列的矩阵 1 2 1 1 每次操作可使一整行或一整列的一个数减少1(如果是0则不变) 问最少多少次操作会使所有的数变为零 分析: 该题很像poj消灭外星人的那道题 思路也差不很多 将x轴当左集合,y轴当右集合,边权值为所在点的数字 那么一条边就代表了矩阵中的一个点 只要找出最小的权值去覆盖所有的边就能把所有的数字变为零 也就是传说中的最小点权覆盖集 最小点权覆盖集 = 最大权匹配 KM跑一遍就可以了 但是需要注意的是如果两边点的个数不相等 那么我们用虚拟点代替就可以了 代码

POJ 3308 Paratroopers (二分图最小点权覆盖 -&gt; 最小割 -&gt; 最大流)

POJ 3308 Paratroopers 链接:http://poj.org/problem?id=3308 题意:有一个N*M的方阵,有L个伞兵降落在方阵上.现在要将所有的伞兵都消灭掉,可以在每行每列装一个高射炮,如果在某行(某列)装上高射炮之后,能够消灭所有落在该行(该列)的伞兵.每行每列安高射炮有费用,问如何安装能够使得费用之积最小. 思路:首先题目要求乘积最小,将乘积对e取对数,会发现就变成了求和.然后抽象出一个二分图,每一行是x部的一个点,每个点有权值,权值为费用取ln.每一列是y部

poj 3308 Paratroopers 最小割 最小点权覆盖

题目链接:http://poj.org/problem?id=3308 题意: 有一个M*N的图,上面的一些点上有伞兵. 可以设置一些枪在每行或者每列上,通过射击,这行或这列的伞兵就会被消灭.每个枪的设置有一个花费,如果设置多个枪,那么花费是设置每个枪的乘积. 问消灭所有伞兵最少的花费是多少. 思路: 每个点的伞兵至少要用那一列或者那一行设置的枪去消灭,那么就可以应用点覆盖的模型.把伞兵看成是一条边,这条边至少要用一个点来覆盖. 而题目中最终花费是所有花费的乘积,那么可以用对数log(x)+lo

poj 3308 Paratroopers(最小点权覆盖)

Paratroopers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8954   Accepted: 2702 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 infor

poj3308 Paratroopers --- 最小点权覆盖-&gt;最小割

题目是一个很明显的二分图带权匹配模型, 添加源点到nx建边,ny到汇点建边,(nx,ny)=inf建边,求最小割既得最小点权覆盖. 在本题中由于求的是乘积,所以先全部取log转换为加法,最后再乘方回来. #include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #inc

POJ 3308--Paratroopers【 最小点权覆盖 &amp;&amp; 最小割】

Paratroopers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7847   Accepted: 2365 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 infor

zoj 2874 &amp; poj 3308 Paratroopers (最小割)

题意: 一个m*n大小的网格,已知伞兵着陆的具体位置(行和列).现在在某行(或某列) 安装一架激光枪,一架激光枪能杀死该行(或该列)所有的伞兵.在第i行安装一架 激光枪的费用是Ri,在第i列安装的费用是Ci.要安装整个激光枪系统,总费用为这些 激光枪费用的乘积. 求杀死所有伞兵的最小费用. 构图: 把伞兵视为边,行与列视为顶点.增加源点和汇点,对于第i行,从源点向顶点i连接一条 容量为Ri的边.对于第j列,从顶点j向汇点连接一条容量为Rj的边. 如果某一点(i,j)有伞兵降落,则从顶点Ri向顶点