BZOJ 4819: [Sdoi2017]新生舞会

二次联通门 : BZOJ 4819: [Sdoi2017]新生舞会

 

 

 

 

/*
    BZOJ 4819: [Sdoi2017]新生舞会

    二分 + 01分数规划 + 最小费用流

    二分出一个答案
    费用流检验

*/
#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>

const int BUF = 12312312;
char Buf[BUF], *buf = Buf;

#define Max 205
inline void read (int &now)
{
    for (now = 0; !isdigit (*buf); ++ buf);
    for (; isdigit (*buf); now = now * 10 + *buf - '0', ++ buf);
}
using std :: min;
using std :: max;

#define INF 1e8
struct E
{
    E *n, *r;
    int to, f;
    double c;
};

class Net_Flow
{
    private :
    
        E poor[Max * Max * 2], *list[Max], *Tail, *pre[Max];    
        int S, T, can[Max];
           double deep[Max];
        bool visit[Max];

    public :
        
        inline void In (int u, int v, int f, double c)
        {
            ++ Tail, Tail->to = v, Tail->n = list[u], list[u] = Tail;
            Tail->c = c, Tail->f = f;
            ++ Tail, Tail->to = u, Tail->n = list[v], list[v] = Tail;
            Tail->c = -c, Tail->f = 0;
            (Tail - 1)->r = Tail, Tail->r = (Tail - 1);
        }    

        inline void Set_ST (int x, int y) { S = x, T = y; }

        bool Bfs ()
        {
            std :: queue <int> Queue; Queue.push (S); can[S] = INF;
            for (register int i = 0; i < Max; ++ i) deep[i] = -INF;
            memset (visit, false, sizeof visit); E *e; int now;
            for (deep[S] = 0, visit[S] = true; !Queue.empty (); Queue.pop ())
            {
                now = Queue.front (); visit[now] = false;
                for (e = list[now]; e; e = e->n)
                    if (e->f && deep[e->to] < deep[now] + e->c)
                    {
                        pre[e->to] = e, can[e->to] = min (can[now], e->f);
                        deep[e->to] = deep[now] + e->c;
                        if (!visit[e->to])
                            visit[e->to] = true, Queue.push (e->to);
                    }
            }
            return deep[T] > -INF;
        }

        double Dinic ()
        {
            double res = 0;
            for (int x; Bfs (); )
            {
                x = can[T];
                for (int t = T; t != S; t = pre[t]->r->to)
                    pre[t]->f -= x, pre[t]->r->f += x;
                res += deep[T];    
            }
            return res;
        }

        void Clear ()
        {
            Tail = poor;
            for (register int i = 0; i < Max; ++ i)
                list[i] = NULL;
        }
};
Net_Flow Flow;

double a[Max][Max], b[Max][Max];

int Main ()
{
    fread (buf, 1, BUF, stdin);

    int N, x; read (N); register int i, j;
    for (i = 1; i <= N; ++ i)
        for (j = 1; j <= N; ++ j)
            read (x), a[i][j] = (double) x;
    for (i = 1; i <= N; ++ i)
        for (j = 1; j <= N; ++ j)
            read (x), b[i][j] = (double) x;
    int S, T; Flow.Set_ST (S = 0, T = (N << 1) + 1);
    double l, r = 1e4, Mid, res;

    for (int Time = 1; Time <= 37; ++ Time)
    {
        Mid = (l + r) / 2.0; Flow.Clear ();
        for (i = 1; i <= N; ++ i)
            Flow.In (S, i, 1, 0), Flow.In (N + i, T, 1, 0);
        for (i = 1; i <= N; ++ i)
            for (j = 1; j <= N; ++ j)
                Flow.In (i, N + j, 1, a[i][j] - b[i][j] * Mid);
        res = Flow.Dinic ();
        if (res <= 0) r = Mid;
        else l = Mid;
    }
    printf ("%.6lf", l);
    return 0;
}
int ZlycerQan = Main ();
int main (int argc, char *argv[]) {;}

 

posted @ 2017-08-23 21:49  ZlycerQan  阅读(224)  评论(0编辑  收藏  举报