Cod sursa(job #2088419)

Utilizator circeanubogdanCirceanu Bogdan circeanubogdan Data 15 decembrie 2017 10:13:29
Problema Bibel Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <fstream>
#define INF 1e9

using namespace std;

ifstream f("bibel.in");
ofstream g("bibel.out");

int n, dp[(1<<17) + 15][17], kk, cnt, tip, ok, sol[17], cntant, kkant;

struct bilele{
    int x, y;
}bila[18], bilaant[18];

int test(int sub, int x){
    return !(sub & (1<<x));
}

int dist(int x, int y, int x2, int y2){
    return (x - x2) * (x - x2) + (y - y2) * (y - y2);
}


int main()
{
	while(true){
    	f>>tip;
    	if(tip == 0){
        	f>>bila[cnt].x>>bila[cnt].y;
        	++ cnt;
    	}
    	if(tip == 1){
            -- cnt;
            if(ok == 1){
                for(int i = 0; i < cntant; ++ i)
                    sol[i] = dp[kk][i];
            }
        	kk = (1<<cnt) - 1;
            for(int i = 1; i < kk; ++ i)
                for(int j = 0; j < cnt; ++ j)
                    dp[i][j] = INF;
            if(ok == 0){
                for(int j = 0; j < cnt; ++ j)
                    dp[kk][j] = INF;
                for(int i = 0; i < cnt; ++ i)
                    dp[(1<<i)][i] = dist(0, 0, bila[i].x, bila[i].y);
            }
            else{
                for(int i = 0; i < cntant; ++ i){
                    for(int j = 0; j < cnt; ++ j){
                        dp[(1<<j)][j] = min (dp[(1<<j)][j], sol[i] + dist(bilaant[i].x, bilaant[i].y, bila[j].x, bila[j].y));
                    }
                }
                for(int j = 0; j < cnt; ++ j)
                    dp[kk][j] = INF;
            }

            for(int i = 1; i <= kk ; ++ i){
                for(int j = 0; j < cnt; ++ j){
                    if(!test(i, j)){
                        for(int k = 0; k < cnt; ++ k){
                            if(test(i, k)){
                                dp[i + (1<<k)][k] = min(dp[i + (1<<k)][k], dp[i][j] + dist(bila[j].x, bila[j].y, bila[k].x, bila[k].y));
                            }
                        }
                    }
                }
            }
        	int minim = INF + 10;
        	for(int i = 0; i < cnt; ++ i){
                minim = min (minim, dp[kk][i]);
                bilaant[i] = bila[i];
        	}
            g<<minim<<'\n';
            cntant = cnt;
            kkant = kk;
            cnt = 0;
            ok = 1;
    	}
    	if(tip == 2)
        	return 0;
	}
	return 0;
}