zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    spark 读取mongodb失败,报executor time out 和GC overhead limit exceeded 异常
    在zepplin 使用spark sql 查询mongodb的数据
    Unable to query from Mongodb from Zeppelin using spark
    spark 与zepplin 版本兼容
    kafka 新旧消费者的区别
    kafka 新生产者发送消息流程
    spark ui acl 不生效的问题分析
    python中if __name__ == '__main__': 的解析
    深入C++的new
    NSSplitView
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3554846.html
Copyright © 2011-2022 走看看