Cod sursa(job #1025871)

Utilizator andrettiAndretti Naiden andretti Data 10 noiembrie 2013 18:03:19
Problema Adapost Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.35 kb
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#define pb push_back
#define maxn 805
#define inf 0x3f3f3f3f
using namespace std;

struct point{double x,y;} a[maxn];
struct edg{double cst;int A,B;} v[maxn*maxn];
int n,S,D,nr,nrm;
int used[maxn],father[maxn],c[maxn][maxn];
double d[maxn],Cost[maxn][maxn];
vector<int> l[maxn];
double flowC;
int vis[405],left[405],right[405],lim;

double dist(point a,point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

void read()
{
    point p;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lf %lf",&a[i].x,&a[i].y);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf %lf",&p.x,&p.y);
        for(int j=1;j<=n;j++)
         v[++nr].cst=dist(a[j],p),v[nr].A=j,v[nr].B=i;
    }
}

bool cmp(const edg &a,const edg &b){
    return a.cst<b.cst;
}

void update(int k)
{
    int x,y;
    for(int i=1;i<=n;i++) l[i].clear();
    for(int i=1;i<=k;i++)
    {
        x=v[i].A; y=v[i].B;
        l[x].pb(y);
    }
    for(int i=1;i<=n;i++) left[i]=right[i]=vis[i]=0;
}

int pair_up(int k)
{
    if(vis[k]==nrm) return 0;
    vis[k]=nrm;
    for(unsigned int i=0;i<l[k].size();i++)
     if(!right[l[k][i]])
     {
         left[k]=l[k][i]; right[l[k][i]]=k;
         return 1;
     }
    for(unsigned int i=0;i<l[k].size();i++)
     if(pair_up(right[l[k][i]]))
     {
         left[k]=l[k][i]; right[l[k][i]]=k;
         return 1;
     }
    return 0;
}

int MMatch()
{
    int ok=1,match=0;
    for(nrm=1;ok;nrm++)
    {
        ok=0;
        for(int i=1;i<=n;i++)
         if(!left[i] && pair_up(i))
          match++,ok=1;
    }
    return match;
}

void solve()
{
    int step,i;
    sort(v+1,v+nr+1,cmp);

    for(step=1;step<nr;step<<=1);
    for(i=0;step;step>>=1)
     if(i+step<=nr)
     {
         update(i+step);
         if(MMatch()==n) lim=i+step;
         else i+=step;
     }
}

void build_graph()
{
    S=0; D=2*n+1;
    for(int i=1;i<=n;i++)
    {
        l[i].clear(); l[i+n].clear();
        c[S][i]=c[i+n][D]=1;
        l[S].pb(i); l[i].pb(S);
        l[i+n].pb(D); l[D].pb(i+n);
    }
    int x,y;
    for(int i=1;i<=lim;i++)
    {
        x=v[i].A; y=v[i].B+n; c[x][y]=1;
        Cost[x][y]=v[i].cst; Cost[y][x]=-v[i].cst;
        l[x].pb(y); l[y].pb(x);
    }
}

int bellman()
{
    queue<int> q;
    int k;

    for(int i=1;i<=D;i++) d[i]=inf,used[i]=0,father[i]=0;
    for(q.push(S),used[S]=1,d[S]=0;!q.empty();q.pop(),used[k]=0)
    {
        k=q.front();
        for(unsigned int i=0;i<l[k].size();i++)
         if(c[k][l[k][i]] && d[k]+Cost[k][l[k][i]]<d[l[k][i]])
         {
             d[l[k][i]]=d[k]+Cost[k][l[k][i]];
             father[l[k][i]]=k;
             if(!used[l[k][i]])
             {
                 q.push(l[k][i]);
                 used[l[k][i]]=1;
             }
         }
    }
    if(d[D]==inf) return 0;
    return 1;
}

void ed_karp()
{
    while(bellman())
    {
        for(int i=D;i!=S;i=father[i])
         c[father[i]][i]--,c[i][father[i]]++;
        flowC+=d[D];
    }
}

int main()
{
    freopen("adapost.in","r",stdin);
    freopen("adapost.out","w",stdout);

    read();
    solve();
    build_graph();
    ed_karp();
    printf("%lf %lf",v[lim].cst,flowC);

    fclose(stdin);
    fclose(stdout);
    return 0;
}