Cod sursa(job #2320878)

Utilizator vlad.ulmeanu30Ulmeanu Vlad vlad.ulmeanu30 Data 15 ianuarie 2019 11:54:36
Problema Bibel Scor 5
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.81 kb
#include <bits/stdc++.h>
#define maxn 17
#define maxt 100
#define inf INT_MAX / 2 - 1
#define pii pair<int,int>
#define fi first
#define se second

using namespace std;

pii v[maxt+5][maxn+5];
pii dp[2][(1<<maxn)+5][maxn+5]; /// dp, loc original
int dst[maxn+5][maxn+5];
int var[maxt+5]; /// indici variante cu scor minim pe nivel
int best[maxn+5];
int szvar;
int ans[maxn+5];

inline int calc_dist ( pii a, pii b )
{
  return (a.fi-b.fi)*(a.fi-b.fi) + (a.se-b.se)*(a.se-b.se);
}

int main ()
{
  ifstream fin ( "bibel.in" );
  ofstream fout ( "bibel.out" );

  int t, n = 0, nv, i, j, conf, conn, niv = 0, p3 = 0, s = 0, smin;

  fin >> t;
  while ( t < 2 )
  {
    if ( t == 1 )
    {
      for ( i = 0; i < n; i++ )
        for ( j = 0; j < n; j++ )
          if ( i != j ) dst[i][j] = calc_dist ( v[niv][i], v[niv][j] );
          else dst[i][j] = inf;

      for ( conf = 0; conf < (1<<n); conf++ )
        for ( i = 0; i < n; i++ )
          dp[p3][conf][i] = {inf,0};

      for ( i = 0; i < n; i++ )
      {
        if ( niv > 0 )
          for ( j = 0; j < nv; j++ )
          {
            if ( dp[p3][1<<i][i].fi > calc_dist(v[niv-1][j], v[niv][i]) )
            {
              best[i] = j; /// unde tb sa ajunga clestele pe niv-1 ai sa am optim pe niv pornind de la i
              dp[p3][1<<i][i] = {calc_dist ( v[niv-1][j], v[niv][i] ), j};
            }
          }
        else
          dp[p3][1<<i][i].fi = calc_dist ( {0, 0}, v[0][i] );
      }

      for ( conf = 0; conf < (1<<n); conf++ )
        for ( i = 0; i < n; i++ )
          if ( (conf & (1<<i)) == 0 )
          {
            conn = conf + (1<<i);
            for ( j = 0; j < n; j++ )
              if ( conf & (1<<j) && dp[p3][conn][i].fi > dp[p3][conf][j].fi + dst[j][i] )
                dp[p3][conn][i] = { dp[p3][conf][j].fi + dst[j][i], dp[p3][conf][j].se};
          }

      ans[niv] = inf;
      for ( i = 0; i < n; i++ )
      {
        ans[niv] = min ( ans[niv], dp[p3][(1<<n)-1][i].fi );
        if ( dp[p3][(1<<n)-1][i].fi < ans[niv] )
        {
          szvar = 0;
          var[szvar++] = dp[p3][(1<<n)-1][i].se;
        }
        else if ( dp[p3][(1<<n)-1][i].fi == ans[niv] )
          var[szvar++] = dp[p3][(1<<n)-1][i].se;
      }

      if ( niv > 0 )
      {
        for ( i = 0, smin = inf; i < szvar; i++ )
        {
          s -= ans[niv-1];
          ans[niv-1] = dp[!p3][(1<<n)-1][var[i]].fi;
          s += ans[niv-1];
          smin = min ( smin, s );
        }
        s = smin + ans[niv];
      }
      else
        s = ans[0];

      fout << s << '\n';
      nv = n; n = 0; niv++; p3 = !p3; szvar = 0;
    }
    else
    {
      fin >> v[niv][n].fi >> v[niv][n].se;
      n++;
    }
    fin >> t;
  }

  fin.close ();
  fout.close ();

  return 0;
}