Cod sursa(job #1936755)

Utilizator pepsiM4A1Ozturk Arif pepsiM4A1 Data 23 martie 2017 13:06:31
Problema Adapost Scor 85
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.67 kb
#include <cstdio>
#include <queue>
#include <vector>
#include <cmath>
#include <cstring>
#include <algorithm>
#define pb push_back
using namespace std;
const int nmax=823,DIM=10000;
int n;
char buff[DIM];
int poz=DIM-1;
vector<int>adj[nmax];
vector<double>vals;
int sursa,dest,c[nmax][nmax],f[nmax][nmax],t[nmax],vis[nmax],l[nmax],r[nmax];
double soldier[2][nmax],refuge[2][nmax],dist[nmax][nmax],d[nmax];
queue<int>q;
void citeste(double &numar)
{
     numar = 0;
     //caut inceputul numarului
     while (buff[poz] < '0' || buff[poz] > '9')
     {
          if (++poz == DIM)
               fread(buff,1,DIM,stdin),poz=0;
     }
     //citesc partea de dinainte de virgula
     while ('0'<=buff[poz] && buff[poz]<='9')
     {
          numar = numar*10 + buff[poz] - '0';
          if (++poz == DIM)
               fread(buff,1,DIM,stdin),poz=0;
     }
     //daca are virgula citesc si partea de dupa
     if (buff[poz] == '.')
     {
          double tmp,cnt;
          tmp = 0;
          cnt = 1;
          ++poz;
          while ('0'<=buff[poz] && buff[poz]<='9')
          {
               cnt = cnt/10;
               tmp = tmp + cnt*(double(buff[poz]-'0'));
               if (++poz == DIM)
                    fread(buff,1,DIM,stdin),poz=0;
          }
          numar += tmp;
     }
}
void citire()
{
    double vr;
    citeste(vr);
    n=(int)vr;
    dest=2*n+1;
    for(int i=1;i<=n;i++) citeste(soldier[0][i]),citeste(soldier[1][i]);
    for(int i=1;i<=n;i++)
    {
        c[sursa][i]=1;
        c[i+n][dest]=1;
        citeste(refuge[0][i]),citeste(refuge[1][i]);
        for(int j=1;j<=n;j++)
        {
            dist[i][j+n]=sqrt((soldier[0][j]-refuge[0][i])*(soldier[0][j]-refuge[0][i])+(soldier[1][j]-refuge[1][i])*(soldier[1][j]-refuge[1][i]));
            vals.pb(dist[i][j+n]);
            dist[j+n][i]=-dist[i][j+n];
            c[i][j+n]=1;
        }
    }
    sort(vals.begin(),vals.end());
}
void create_graph(const double &val)
{
    for(int i=1;i<=n;i++)
    {
        adj[sursa].pb(i);
        adj[i].pb(sursa);
        adj[dest].pb(i+n);
        adj[i+n].pb(dest);
        for(int j=1;j<=n;j++)
        {
            if(dist[i][j+n]<=val)
            {
                adj[i].pb(j+n);
                adj[j+n].pb(i);
            }
        }
    }
}
int bellman()
{
    for(int i=sursa;i<=dest;i++)
    {
        vis[i]=0;
        t[i]=-1;
        d[i]=0x3f3f3f3f;
    }
    q.push(sursa);
    vis[sursa]=1;
    d[sursa]=0;
    while(!q.empty())
    {
        int nod=q.front();
        q.pop();
        for(vector<int>::iterator it=adj[nod].begin();it!=adj[nod].end();++it)
        {
            if(c[nod][*it]-f[nod][*it]<=0) continue;
            if(d[*it]>d[nod]+dist[nod][*it])
            {
                d[*it]=d[nod]+dist[nod][*it];
                t[*it]=nod;
                if(vis[*it]) continue;
                vis[*it]=1;
                q.push(*it);
            }
        }
        vis[nod]=0;
    }
    if(d[dest]==0x3f3f3f3f) return 0;
    return 1;
}
double do_flow()
{
    double sol=0;
    while(bellman())
    {
        int minim=0x3f3f3f3f;
        for(int i=dest;i!=sursa;i=t[i]) minim=min(minim,c[t[i]][i]-f[t[i]][i]);
        sol+=minim*d[dest];
        for(int i=dest;i!=sursa;i=t[i])
        {
            f[t[i]][i]+=minim;
            f[i][t[i]]-=minim;
        }
    }
    return sol;
}
int pairup(int nod,double x)
{
    if(vis[nod]) return 0;
    vis[nod]=1;
    for(int j=1;j<=n;j++)
    {
        if(dist[nod][j+n]<=x&&(r[j]==0))
        {
            l[nod]=j;
            r[j]=nod;
            return 1;
        }
    }
    for(int j=1;j<=n;j++)
    {
        if(dist[nod][j+n]<=x&&(pairup(r[j],x)))
        {
            l[nod]=j;
            r[j]=nod;
            return 1;
        }
    }
    return 0;
}
int do_flow2(double x)
{
    for(int i=1;i<=n;i++) l[i]=0,r[i]=0;
    for(int c=1;c!=0;)
    {
        c=0;
        for(int i=1;i<=n;i++)
        {
            if(l[i]==0) c|=pairup(i,x);
        }
        for(int i=1;i<=n;i++) vis[i]=0;
    }
    int sum=0;
    for(int i=1;i<=n;i++) if(l[i]!=0) ++sum;
    return sum;
}
inline void do_bs()
{
    int dr=vals.size();
    int step=1;
    while((step<<1)<=dr) step<<=1;
    int rasp=0;
    for(;step>=1;step>>=1)
    {
        if(rasp+step<=dr)
        {
            int vrr=do_flow2(vals[rasp+step-1]);
            if(vrr<n) rasp+=step;
        }
    }
    create_graph(vals[rasp]);
    printf("%lf %lf\n",vals[rasp],do_flow());
}
int main()
{
    freopen ("adapost.in","r",stdin);
    freopen ("adapost.out","w",stdout);
    citire();
    do_bs();
}