• POJ 3308 Paratroopers(最小割EK)


    题目链接

    题意 : 有一个n*m的矩阵,L个伞兵可能落在某些点上,这些点的坐标已知,需要在某些位置安上一些枪,然后每个枪可以将一行或者一列的伞兵击毙。把这种枪安装到不同行的行首、或者不同列的列首,费用都不同。现在已知把激光枪安装到任意位置的费用,总的花费为这些安装了激光枪的行列花费的乘积。

    思路 :就是一个最大流问题。Dinic我不会,用的白皮书上的EK算法,嗯,还行,这个建图比较麻烦,就是把行列分开,成为m+n+1个点。嗯,不废话了,还是把大神博客链接弄过来吧,各方面都讲得很详细。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    #include <math.h>
    
    using namespace std;
    
    const int maxn = 300 ;
    const int INF = 99999999 ;
    double a[maxn],cap[maxn][maxn],flow[maxn][maxn] ;
    double f ;
    int p[maxn] ;
    int m,n,l;
    
    void EK(int s)
    {
        queue<int>Q ;
        memset(flow,0,sizeof(flow)) ;
        f = 0 ;
        for( ; ; )
        {
            memset(p,-1,sizeof(p)) ;
            memset(a,0,sizeof(a)) ;
            a[s] = INF ;
            Q.push(s) ;
            while(!Q.empty())
            {
                int u = Q.front() ;Q.pop() ;
                for(int v = 0 ; v <= m+n+1 ; v++)
                {
                    if(!a[v] && cap[u][v] > flow[u][v])
                    {
                        p[v] = u ;
                        Q.push(v) ;
                        a[v] = min(a[u],cap[u][v]-flow[u][v]) ;
                    }
                }
            }
            if(a[m+n+1] == 0) break ;
            for(int u = m+n+1 ; u != 0 ; u = p[u])
            {
                flow[p[u]][u] += a[m+n+1] ;
                flow[u][p[u]] -= a[m+n+1] ;
            }
            f += a[m+n+1] ;
        }
    }
    int main()
    {
        int T;
        scanf("%d",&T) ;
        while(T--)
        {
            memset(cap,0,sizeof(cap)) ;
            f = 0 ;
            double s ;
            int x,y ;
            scanf("%d %d %d",&m,&n,&l) ;
            for(int i = 1 ; i <= m ; i++)
            {
                scanf("%lf",&s) ;
                cap[0][i] = log(s) ;
            }
            for(int i = m+1 ; i <= m+n ; i++)
            {
                scanf("%lf",&s) ;
                cap[i][m+n+1] = log(s) ;
            }
            for(int i = 0 ; i < l ; i++)
            {
                scanf("%d %d",&x,&y) ;
                cap[x][m+y] = INF ;
            }
            EK(0) ;
            printf("%.4f
    ",exp(f)) ;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Filesystem Case-Sensitivity Mismatch
    内存分配
    单链表
    PHP校验日期格式是否合法
    Automatically populating $HTTP_RAW_POST_DATA is deprecated
    preg_match(): Compilation failed: character value in x{} or o{} is too large at offset 8
    CGI 和 FastCGI 协议的运行原理
    冒泡排序
    油猴子脚本-过滤百度广告
    查看chrome插件源码
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3554846.html
Copyright © 2020-2023  润新知