Cod sursa(job #2857430)

Utilizator puica2018Puica Andrei puica2018 Data 25 februarie 2022 16:31:20
Problema Bibel Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <bits/stdc++.h>

using namespace std;

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

int t,x,y;
vector <pair <int,int>> a,b;
int cnt;
long long odp[1<<17][17],newdp[1<<17][17];

long long dist(int x1,int y1,int x2,int y2)
{
    return 1LL*(x2-x1)*(x2-x1)+1LL*(y2-y1)*(y2-y1);
}

long long solve1()
{
    int x=a.size();
    for(int bit=0; bit<x; bit++)
        odp[1<<bit][bit]=dist(0,0,a[bit].first,a[bit].second);
    for(int mask1=1; mask1<(1<<x); mask1++)
    {
        if(__builtin_popcount(mask1)==1) continue;
        for(int bit1=0; bit1<x; bit1++)
        {
            if((mask1>>bit1)&1)
            {
                odp[mask1][bit1]=1e18;
                int mask2=mask1^(1<<bit1);
                for(int bit2=0; bit2<x; bit2++)
                    if((mask2>>bit2)&1)
                        odp[mask1][bit1]=min(odp[mask1][bit1],odp[mask2][bit2]+dist(a[bit2].first,a[bit2].second,a[bit1].first,a[bit1].second));
            }
        }
    }
    long long minim=1e18;
    for(int bit=0; bit<x; bit++)
        minim=min(minim,odp[(1<<x)-1][bit]);
    return minim;
}

long long solve2()
{
    int x=a.size(),y=b.size();
    for(int bit1=0; bit1<x; bit1++)
    {
        newdp[1<<bit1][bit1]=1e18;
        for(int bit2=0; bit2<y; bit2++)
            newdp[1<<bit1][bit1]=min(newdp[1<<bit1][bit1],odp[(1<<y)-1][bit2]+dist(b[bit2].first,b[bit2].second,a[bit1].first,a[bit1].second));
    }
    for(int mask1=1; mask1<(1<<x); mask1++)
    {
        if(__builtin_popcount(mask1)==1) continue;
        for(int bit1=0; bit1<x; bit1++)
        {
            newdp[mask1][bit1]=1e18;
            if((mask1>>bit1)&1)
            {
                int mask2=mask1^(1<<bit1);
                for(int bit2=0; bit2<x; bit2++)
                    if((mask2>>bit2)&1)
                        newdp[mask1][bit1]=min(newdp[mask1][bit1],newdp[mask2][bit2]+dist(a[bit2].first,a[bit2].second,a[bit1].first,a[bit1].second));
            }
        }
    }
    for(int mask=1; mask<(1<<x); mask++)
        for(int bit=0; bit<x; bit++)
            odp[mask][bit]=newdp[mask][bit];
    long long minim=1e18;
    for(int bit=0; bit<x; bit++)
        minim=min(minim,newdp[(1<<x)-1][bit]);
    return minim;
}

int main()
{
    while(fin>>t)
    {
        if(t==0)
        {
            fin>>x>>y;
            a.push_back(make_pair(x,y));
        }
        if(t==1)
        {
            if(cnt==0) fout<<solve1()<<"\n";
            else fout<<solve2()<<"\n";
            b=a;
            a.clear();
            cnt++;
        }
        if(t==2)
            return 0;
    }
    return 0;
}