Pagini recente » Cod sursa (job #1165342) | Cod sursa (job #1193361) | Cod sursa (job #1637245) | Cod sursa (job #3179246) | Cod sursa (job #117248)
Cod sursa(job #117248)
Utilizator |
Andrei Grigorean wefgef |
Data |
20 decembrie 2007 23:43:37 |
Problema |
Bibel |
Scor |
Ascuns |
Compilator |
cpp |
Status |
done |
Runda |
|
Marime |
2.25 kb |
#include <cassert>
#include <cstdio>
#include <climits>
#include <vector>
#include <algorithm>
using namespace std;
#define maxL 17
struct pnt {
int x, y;
};
int M;
vector<pnt> curr;
vector<int> curr_dist;
vector<pnt> last;
vector<int> last_dist;
int mat[1 << maxL][maxL];
inline int dist(const pnt& p1, const pnt& p2) {
#define SQR(x) ((x)*(x))
return SQR(p1.x-p2.x) + SQR(p1.y-p2.y);
#undef SQR
}
int do_din() {
memset(mat, 0xff, sizeof(mat));
for (int j = 0; j < (int)curr.size(); ++j) {
int& ret = mat[1 << j][j];
ret = INT_MAX;
for (int i = 0; i < (int)last.size(); ++i)
ret = min(ret, dist(last[i], curr[j]) + last_dist[i]);
}
int prec[maxL][maxL];
for (int i = 0; i < (int)curr.size(); ++i)
for (int j = 0; j < (int)curr.size(); ++j) {
prec[i][j] = dist(curr[i], curr[j]);
}
for (int conf = 0; conf < (1 << curr.size()); ++conf) {
int temp[maxL], count = 0;
for (int i = 0; i < maxL; ++i)
if (conf & (1 << i)) temp[count++] = i;
for (int last = 0; last < (int)curr.size(); ++last) {
if (!(conf & (1 << last))) continue;
if (conf == (1 << last)) continue;
int& ret = mat[conf][last];
ret = INT_MAX;
conf ^= 1 << last;
for (int i = 0; i < count; ++i)
if (temp[i] != last)
ret = min(ret, mat[conf][temp[i]] +
prec[temp[i]][last]);
conf ^= 1 << last;
}
}
for (int j = 0; j < (int)curr.size(); ++j)
curr_dist.push_back(mat[(1 << curr.size()) - 1][j]);
return *min_element(curr_dist.begin(), curr_dist.end());
}
int main() {
freopen("bibel.in", "rt", stdin);
freopen("bibel.out", "wt", stdout);
last.push_back((pnt){0, 0});
last_dist.push_back(0);
while (1) {
int op;
scanf("%d", &op);
assert(0 <= op && op <= 2);
switch (op) {
case 0: {
int x, y;
scanf("%d %d", &x, &y);
assert(0 <= x && x <= 10000);
assert(0 <= y && y <= 10000);
curr.push_back((pnt){x, y});
break;
}
case 1: {
assert(curr.size() <= maxL);
int result = do_din();
printf("%d\n", result);
curr.swap(last);
curr.clear();
curr_dist.swap(last_dist);
curr_dist.clear();
break;
}
case 2: {
return 0;
}
}
}
return 0;
}