zoukankan      html  css  js  c++  java
  • poj3308 Paratroopers --- 最小点权覆盖->最小割

    题目是一个非常明显的二分图带权匹配模型,

    加入源点到nx建边,ny到汇点建边,(nx。ny)=inf建边。求最小割既得最小点权覆盖。

    在本题中因为求的是乘积,所以先所有取log转换为加法,最后再乘方回来。


    #include <iostream>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <map>
    #define inf 0x3f3f3f3f
    #define eps 1e-6
    #define ll __int64
    const int maxn=110;
    using namespace std;
    
    int n,s,t,level[maxn];
    double c[maxn][maxn];
    
    bool makelevel()
    {
        memset(level,0,sizeof level);
        level[s]=1;
        int q[maxn];
        int fro=0,iq=0;
        q[iq++]=s;
        int i,v;
        while(fro!=iq)
        {
            v=q[fro++];
            for(i=0;i<=t;i++)
            {
                if(!level[i]&&c[v][i])
                {
                    level[i]=level[v]+1;
                    q[iq++]=i;
                }
            }
        }
        if(!level[t]) return 0;
        return 1;
    }
    
    double dfs(int now,double maxf)
    {
        if(now==t) return maxf;
        double ret=0;
        for(int i=0;maxf!=0&&i<=t;i++)
        {
            if(c[now][i]&&level[now]+1==level[i])
            {
                double tmp=dfs(i,min(maxf,c[now][i]));
                c[now][i]-=tmp;
                c[i][now]+=tmp;
                ret+=tmp;
                maxf-=tmp;
            }
        }
        return ret;
    }
    
    double dinic()
    {
        double ans=0;
        while(makelevel()) ans+=dfs(s,10000000);
        return ans;
    }
    
    int main()
    {
        int icy,m,l,i,aa,bb;
        double a,b;
        scanf("%d",&icy);
        while(icy--)
        {
            scanf("%d%d%d",&m,&n,&l);
            s=0;t=n+m+1;
            memset(c,0,sizeof c);
            for(i=1;i<=m;i++)
            {
                scanf("%lf",&a);
                c[0][i]=log(a);
            }
            for(i=1;i<=n;i++)
            {
                scanf("%lf",&a);
                c[i+m][t]=log(a);
            }
            for(i=0;i<l;i++)
            {
                scanf("%d%d",&aa,&bb);
                c[aa][bb+m]=10000000;
            }
            printf("%.4lf
    ",exp(dinic()));
        }
        return 0;
    }
    


  • 相关阅读:
    apue学习笔记(第十五章 进程间通信)
    apue学习笔记(第十四章 高级I/O)
    apue学习笔记(第十三章 守护进程)
    各种仪器销售说明网站
    专业英语分类和查询
    c#网格控件,Excel控件
    sqlite支持linq
    使WebDev.WebServer.exe 当web服务器
    zip压缩文件测试
    c++爬虫子
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5191236.html
Copyright © 2011-2022 走看看