Cod sursa(job #1709925)

Utilizator linia_intaiConstantinescu Iordache Ciobanu Noi cei din linia intai linia_intai Data 28 mai 2016 14:26:01
Problema Metrou4 Scor 0
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 4.6 kb
#include<iostream>
#include<fstream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<math.h>

#define NMAX 150001
#define MMAX 1500001
#define INF (1LL << 62)


FILE* in=fopen("metrou4.in","r");
FILE* out=fopen("metrou4.out","w");

struct punct
{
    long long x,y,nr;
};

struct cmp
{
    bool operator () (const punct &a, const punct &b) const
    {
        if((a.x+a.y)==(b.x+b.y))
            return a.y>b.y;
        return (a.x+a.y)<(b.x+b.y);
    }
};

struct muchie
{
    long long x,y,cost;
    bool operator < (const muchie &c) const
    {
        return cost<c.cost;
    }
};

muchie v[MMAX];
long long kept[NMAX],rang[NMAX],nrmuchii;
punct myvect[NMAX],init[NMAX];
long long arinit[4*NMAX],parinit[4*NMAX],valmax,pvalmax;

void put_aib(long long nod, long long st, long long dr, long long poz, long long val, long long nr)
{
    long long mij;
    if(st==dr)
    {
        if(val>arinit[nod])
        {
            arinit[nod]=val;
            parinit[nod]=nr;
        }
        return ;
    }
    mij=(st+dr)/2;
    if(poz<=mij)
        put_aib(nod*2,st,mij,poz,val,nr);
    else put_aib(nod*2+1,mij+1,dr,poz,val,nr);
    if(arinit[nod*2]>arinit[2*nod+1])
    {
        arinit[nod]=arinit[nod*2];
        parinit[nod]=parinit[nod*2];
    }
    else
    {
        arinit[nod]=arinit[nod*2+1];
        parinit[nod]=parinit[nod*2+1];
    }
}

void ask_aib(long long nod, long long st, long long dr, long long aa, long long bb)
{
    long long mij;
    if(aa<=st && dr<=bb)
    {
        if(arinit[nod]>valmax)
        {
            valmax=arinit[nod];
            pvalmax=parinit[nod];
        }
        return ;
    }
    mij=(st+dr)/2;
    if(aa<=mij)
        ask_aib(nod*2,st,mij,aa,bb);
    if(mij<bb)
        ask_aib(nod*2+1,mij+1,dr,aa,bb);
}

inline long long dist(punct aa, punct bb)
{
    return abs(aa.x-bb.x) + abs(aa.y-bb.y);
}

void compute(long long n)
{
    long long i,j,x;
    std::sort(myvect+1,myvect+n+1,cmp());
    for(i=0; i<=4*n; i++)
        arinit[i]=-INF;
    put_aib(1,1,n,myvect[1].y,myvect[1].x-myvect[1].y,1);
    for(i=2; i<=n; i++)
    {
        valmax=-INF;
        ask_aib(1,1,n,myvect[i].y,n);
        if(valmax!=-INF)
        {
            nrmuchii++;
            v[nrmuchii].x=myvect[pvalmax].nr;
            v[nrmuchii].y=myvect[i].nr;
            v[nrmuchii].cost=dist(myvect[pvalmax],myvect[i]);
        }
        put_aib(1,1,n,myvect[i].y,myvect[i].x-myvect[i].y,i);
    }
}

inline long long multime(long long x)
{
    long long r,aux;
    r=x;
    while(r!=kept[r])
        r=kept[r];
    while(x!=kept[x])
    {
        aux=kept[x];
        kept[x]=r;
        x=aux;
    }
    return r;
}

inline void uneste(long long x, long long y)
{
    x=multime(x);
    y=multime(y);
    if(rang[x]<rang[y])
        kept[x]=y;
    else if(rang[x]>rang[y])
        kept[y]=x;
    else
    {
        kept[x]=y;
        rang[y]++;
    }
}

long long finalize(long long n, long long m)
{
    long long i,cmin,k;
    std::sort(v+1,v+m+1);
    for(i=1; i<=n; i++)
    {
        kept[i]=i;
        rang[i]=1;
    }
    cmin=0;
    k=0;
    for(i=1; i<=m && k<=n-1; i++)
    {
        if(multime(v[i].x)==multime(v[i].y))
            continue;
        cmin=cmin+v[i].cost;
        uneste(v[i].x,v[i].y);
        k++;
    }
    return cmin;
}

void main2()
{
    memset(v,0,sizeof v);
    memset(parinit,0,sizeof parinit);
    nrmuchii=0;

    long long n,i;

    fscanf(in,"%lld",&n);
    for(i=1; i<=n; i++)
    {
        fscanf(in,"%lld%lld",&init[i].x,&init[i].y);
        init[i].nr=i;
    }
    for(i=1; i<=n; i++)
        myvect[i]=init[i];
    compute(n);
    for(i=1; i<=n; i++)
    {
        myvect[i].nr=init[i].nr;myvect[i].x=-init[i].y;myvect[i].y=-init[i].x;
    }
    compute(n);
    for(i=1; i<=n; i++)
    {
        myvect[i].nr=init[i].nr;myvect[i].x=-init[i].y;myvect[i].y=init[i].x;
    }
    compute(n);
    for(i=1; i<=n; i++)
    {
        myvect[i].nr=init[i].nr;myvect[i].x=-init[i].x;myvect[i].y=init[i].y;
    }
    compute(n);
    for(i=1; i<=n; i++)
    {
        myvect[i].nr=init[i].nr;myvect[i].x=-init[i].x;myvect[i].y=-init[i].y;
    }
    compute(n);
    for(i=1; i<=n; i++)
    {
        myvect[i].nr=init[i].nr;myvect[i].x=init[i].y;myvect[i].y=init[i].x;
    }
    compute(n);
    for(i=1; i<=n; i++)
    {
        myvect[i].nr=init[i].nr;myvect[i].x=init[i].y;myvect[i].y=-init[i].x;
    }
    compute(n);
    for(i=1; i<=n; i++)
    {
        myvect[i].nr=init[i].nr;myvect[i].x=init[i].x;myvect[i].y=-init[i].y;
    }
    compute(n);

    fprintf(out,"%lld\n", finalize(n,nrmuchii) );
}

signed main()
{
    long long t;

    fscanf(in,"%lld",&t);

    while(t)
    {
        t--;
        main2();
    }

    return 0;
}