zoukankan      html  css  js  c++  java
  • [SDOI 2017] 新生舞会

    [题目链接]

             https://www.lydsy.com/JudgeOnline/problem.php?id=4819

    [算法]

            很明显的0 / 1分数规划问题

            首先二分答案 , 显然 , 若 sigma(Aij - mid * Bij) >= 0 , 说明有比mid更优的解

            用费用流 / KM算法检验即可

            时间复杂度 : O(N^3logN)

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 110
    const double inf = 1e15;
    const double EPS = 1e-9;
    
    int n;
    double delta;
    int match[MAXN];
    int a[MAXN][MAXN] , b[MAXN][MAXN];
    double la[MAXN] , lb[MAXN];
    double c[MAXN][MAXN];
    bool visiteda[MAXN] , visitedb[MAXN];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline bool dfs(int u)
    {
            visiteda[u] = true;
            for (int i = 1; i <= n; i++)
            {
                    if (!visitedb[i])
                    {
                            if (fabs(la[u] + lb[i] - c[u][i]) < EPS) 
                            {
                                    visitedb[i] = true;
                                    if (!match[i] || dfs(match[i]))
                                    {
                                            match[i] = u;
                                            return true;
                                    }
                            } else chkmin(delta , la[u] + lb[i] - c[u][i]);
                    }
             }
             return false;
    }
    inline double KM()
    {
            for (int i = 1; i <= n; i++)
            {
                    la[i] = -inf;
                    lb[i] = 0;
                    match[i] = 0;
                    for (int j = 1; j <= n; j++) chkmax(la[i] , c[i][j]);
            }
            for (int i = 1; i <= n; i++)
            {
                    while (true)
                    {
                            delta = inf;
                            for (int j = 1; j <= n; j++) visiteda[j] = visitedb[j] = false;
                            if (dfs(i)) break;
                            for (int j = 1; j <= n; j++) 
                            {
                                    if (visiteda[j]) la[j] -= delta;
                                    if (visitedb[j]) lb[j] += delta;
                            }
                    }
            }
            double ret = 0;
            for (int i = 1; i <= n; i++) ret += c[match[i]][i];
            return ret;
    }
    inline bool check(double mid)
    {
            for (int i = 1; i <= n; i++)
            {
                    for (int j = 1; j <= n; j++)
                    {
                            c[i][j] = 1.0 * a[i][j] - 1.0 * b[i][j] * mid;        
                    }        
            }        
            if (KM() >= 0) return true;
            else return false;
    }
    
    int main()
    {
            
            read(n);
            for (int i = 1; i <= n; i++)
            {
                    for (int j = 1; j <= n; j++)
                    {
                            read(a[i][j]);
                    }
            }
            for (int i = 1; i <= n; i++)
            {
                    for (int j = 1; j <= n; j++)
                    {
                            read(b[i][j]);
                    }
            }
            double l = 0 , r = (int)1e4 , ans = 0;
            while (l + EPS < r)
            {
                    double mid = (l + r) / 2.0;
                    if (check(mid))
                    {
                            ans = mid;
                            l = mid;        
                    }    else r = mid;
            }
            printf("%.6lf
    " , ans);
            
            return 0;
        
    }
  • 相关阅读:
    深入了解Go Playground
    计算机程序设计艺术学习笔记1
    Docker 和一个正常的虚拟机有何区别?
    现代计算机架构常见时延(摘自计算机系统结构--量化研究方法)
    内核开发时应该注意的点
    gem5线程相关的类—SimpleThread类,ThreadState类(src/cpu/thread_state.*)
    GEM5中模拟的系统调用(部分没实现)
    字典树(trie)
    UML类图几种关系的总结
    C,C++宏中#与##的讲解
  • 原文地址:https://www.cnblogs.com/evenbao/p/9858443.html
Copyright © 2011-2022 走看看