Cod sursa(job #1709759)

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

#define NMAX 100001
#define MMAX 1000001
#define INF 1<<30


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

struct punct
{
    int 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
{
    int x,y,cost;
    bool operator < (const muchie &c) const
    {
        return cost<c.cost;
    }
};

muchie v[MMAX];
std::vector <muchie> sol;
int kept[NMAX],rang[NMAX],nrmuchii;
punct myvect[NMAX],init[NMAX];
int arinit[4*NMAX],parinit[4*NMAX],valmax,pvalmax;

void put_aib(int nod, int st, int dr, int poz, int val, int nr)
{
    int 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(int nod, int st, int dr, int aa, int bb)
{
    int 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 int dist(punct aa, punct bb)
{
    return abs(aa.x-bb.x) + abs(aa.y-bb.y);
}

void compute(int n)
{
    int 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 int multime(int x)
{
    int 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(int x, int 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]++;
    }
}

int finalize(int n, int m)
{
    int 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;
        sol.push_back(v[i]);
        uneste(v[i].x,v[i].y);
        k++;
    }
    return cmin;
}

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

    int n,i;

    fscanf(in,"%d",&n);
    for(i=1; i<=n; i++)
    {
        fscanf(in,"%d%d",&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,"%d\n", finalize(n,nrmuchii) );
}

int main()
{
    int t;

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

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

    return 0;
}