Cod sursa(job #64912)

Utilizator fireatmyselfBogdan-Alexandru Stoica fireatmyself Data 6 iunie 2007 11:00:52
Problema Adapost Scor 9
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.06 kb
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>


#define NMAX 404
#define QMAX ((1<<16)-1)
#define INF 666000666
#define eps 1e-4
#define f first
#define s second

using namespace std;

int N, Cup[NMAX], F[NMAX], Fl[NMAX][NMAX], C[NMAX][NMAX];
vector<pair<double,int> > D[NMAX];
double X[NMAX], Y[NMAX], Rmin, Dmin, Dd[NMAX][NMAX<<1], Dist[NMAX<<1];
int t[NMAX<<1], inQ[NMAX<<1], Q[QMAX+10], cup[NMAX<<1], type[NMAX<<1];

void read()
{
        int i, j;
        double x, y;

        freopen("adapost.in", "r", stdin);
        scanf("%d", &N);

        for (i = 1; i <= N; i++)
            { scanf("%lf %lf", &X[i], &Y[i]); D[i].push_back(make_pair(-INF,0)); }

        for (i = 1; i <= N; i++)
        {
                scanf("%lf %lf", &x, &y);
                for (j = 1; j <= N; j++)
                {
                    D[j].push_back(make_pair(sqrt( (X[j]-x)*(X[j]-x) + (Y[j]-y)*(Y[j]-y) ), i));
                    Dd[j][i] = D[j][i].f;
                }
        }

        for (i = 1; i <= N; i++) sort(D[i].begin(), D[i].end());
}

int pairthembaby(int i, double dmax)
{
        int j, x;
        
        if (F[i]) return 0;
        F[i] = 1;
        for (j = 1; j <= N && D[i][j].f <= dmax; j++)
            if ((!Cup[ D[i][j].s ]) || (pairthembaby(Cup[D[i][j].s], dmax)))
            {
                Cup[ D[i][j].s ] = i;
                return 1;
            }
        return 0;
}

void joint(double dmax)
{
        int i;

        for (i = 1; i <= N; i++)
            if (!pairthembaby(i,dmax))
            {
                memset(F,0,sizeof(F));
                pairthembaby(i,dmax);
            }
}

void findsum(int tap)
{
        int i, j, lo, hi;
        double min;

        for (i = 0; i < NMAX<<1; i++)
            t[i] = inQ[i] = type[i] = 0, Dist[i] = INF;

        Dist[tap] = 0; inQ[tap] = 1; Q[0] = tap; t[tap] = -1;

        for (lo = 0, hi = 1; lo != hi; lo=(lo+1)&QMAX)
        {
                i = Q[lo];
                if (i <= N)
                {
                   for (j = N+1; j <= N<<1; j++)
                       if ( (Fl[i][j]<C[i][j]) && (Dist[j]>Dist[i]+Dd[i][j]) )
                       {
                                Dist[j] = Dist[i]+Dd[i][j];
                                t[j] = i; type[j] = 1;
                                if (!inQ[j]) inQ[j] = 1, Q[hi] = j, hi = (hi+1)&QMAX;
                       }
                }
                else
                {
                        if ( (cup[i]) && (Fl[cup[i]][i]>0) && (Dist[cup[i]] > Dist[i]-Dd[cup[i]][i]) )
                        {
                                Dist[cup[i]] = Dist[i]-Dd[cup[i]][i];
                                t[cup[i]] = i; type[cup[i]] = 2;
                                if (!inQ[cup[i]]) inQ[cup[i]] = 1, Q[hi] = cup[i], hi = (hi+1)&QMAX;
                        }
                }
        }

        min = INF; j = tap;
        for (i = N+1; i <= N<<1; i++)
            if (!cup[i] && Dist[i]<min) min = Dist[i], j = i;

        Dmin += min;
        for (i = j; i > 0; i=t[i])
            if (type[i]==1)
            {
                Fl[t[i]][i]++;
                cup[i] = t[i];
            }
            else Fl[i][t[i]]--;
}

void solve()
{
        int flow, i, j;
        double lo = 0, hi = (1<<28), mij;

        while (lo<=hi)
        {
                mij = (lo+hi)/2.0;
                memset(Cup,0,sizeof(Cup));
                joint(mij);
                for (i = 1, flow = 0; i <= N; i++) flow += (Cup[i]>0);
                if (flow == N) Rmin = mij, hi = mij-eps;
                else lo = mij+eps;
        }

        for (i = 1; i <= N; i++)
            for (j = 1; j <= N; j++)
                if (Dd[i][j] <= Rmin) C[i][N+j] = 1, Dd[i][N+j] = Dd[i][j];

        for (i = 1; i <= N; i++) findsum(i);
}

void write()
{
        freopen("adapost.out", "w", stdout);
        printf("%lf %lf\n", Rmin, Dmin);
}

int main()
{
        read();
        solve();
        write();
        return 0;
}