문제: icpc.me/14431
마을의 좌표가 주어질 때 두 좌표사이의 거리의 정수부분이 소수일 경우에만 이동가능한다는 조건하에 소수마을에서 A마을로 이동하는데 걸리는 최단경로를 구하는 문제이다.
에라토스테네스의 체를 이용하여 소수들을 구해준 후 거리가 소수인 정점들을 서로 간선 연결을 해준 뒤 다익스트라를 돌려서 해결하면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #include <cstdio> #include <algorithm> #include <vector> #include <queue> #include <cstring> using namespace std; int getdist(pair<int,int> a, pair<int,int> b) { return sqrt((a.first - b.first)*(a.first - b.first) + (a.second - b.second)*(a.second - b.second)); } pair<int, int> a[4010], e; int n, dp[4010]; bool p[10000000]; vector<vector<pair<int, int>>> vt; int main(){ p[0] = p[1] = true; for (int i = 2; i <= 9999999; i++) { if (p[i])continue; for (int j = i + i; j <= 9999999; j += i) { p[j] = true; } } scanf("%d%d%d%d", &a[0].first, &a[0].second, &e.first, &e.second); scanf("%d", &n); a[n + 1] = e; vt.resize(n + 2); for (int i = 1; i <= n; i++) scanf("%d%d", &a[i].first, &a[i].second); for (int i = 0; i <= n + 1; i++) { for (int j = i + 1; j <= n + 1; j++) { int d = getdist(a[i], a[j]); if (!p[d]) { vt[i].push_back({ j,d }); vt[j].push_back({ i,d }); } } } memset(dp, -1, sizeof(dp)); priority_queue<pair<int, int>> pq; pq.push({ 0,0 }); while (pq.size()) { int here = pq.top().second; int cost = -pq.top().first; pq.pop(); if (dp[here] != -1)continue; dp[here] = cost; if (here == n + 1)break; for (auto next : vt[here]) { if (dp[next.first] != -1)continue; pq.push({ -cost - next.second,next.first }); } } printf("%d\n", dp[n + 1]); return 0; } | cs |
'알고리즘 관련 > BOJ' 카테고리의 다른 글
BOJ)1562 계단 수 (0) | 2017.02.06 |
---|---|
BOJ)14433 한조 대기 중 (0) | 2017.02.06 |
BOJ) 10282 Failing Components (0) | 2017.02.04 |
BOJ)9202 Boggle (0) | 2017.02.04 |
BOJ)5052 전화번호 목록 (0) | 2017.02.03 |