Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit af34595

Browse files
서강 그라운드
1 parent 71181b6 commit af34595

File tree

1 file changed

+160
-0
lines changed

1 file changed

+160
-0
lines changed

‎challenges/BOJ14938.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# 문제
2+
서강 그라운드
3+
## 문제 원본
4+
문제의 원본은 [여기서](https://www.acmicpc.net/problem/14938) 확인하세요.
5+
6+
## 분류
7+
* 플로이드 와샬
8+
9+
# 풀이
10+
11+
플로이드 와샬에서 A배열 업데이트 과정에서 최단 거리가 탐색 범위를 초과 하지 않도록 조건을 걸어준다. 그 후 A배열이 업데이트 될때 `N[i][j]`의 값을 업데이트 하는데 이 `N[i][j]`의 값은 정점 i에서 시작했을때 정점 j에서 얻는 아이템의 수이다. 결과는 N배열에서 모든 i에서 j에 대한 합이 최대가 되는 값을 출력한다.
12+
13+
``` c++
14+
#include <iostream>
15+
#include <algorithm>
16+
#include <vector>
17+
18+
#define INF 10000000
19+
20+
using namespace std;
21+
22+
23+
class Graph {
24+
public:
25+
int n;
26+
vector<pair<int, int>>* adj;
27+
int *nItems; // 정점에서 얻을 수 잇는 아이템수
28+
29+
Graph(int n) {
30+
this->n = n;
31+
adj = new vector<pair<int, int>>[n + 1];
32+
nItems = new int[n + 1];
33+
nItems[0] = 0;
34+
}
35+
36+
// 간선 추가
37+
void insertEdge(int u, int v, int w) {
38+
this->adj[u].push_back(make_pair(v, w));
39+
this->adj[v].push_back(make_pair(u, w));
40+
}
41+
42+
// 정점 v에서 얻을 수 있는 아이템 수 설정
43+
void setNItems(int v, int n) {
44+
nItems[v] = n;
45+
}
46+
};
47+
48+
void input(Graph* g, int nVertices, int nEdges) {
49+
for (int i = 1; i < nVertices + 1; i++) {
50+
int nItems;
51+
cin >> nItems;
52+
g->setNItems(i, nItems);
53+
}
54+
55+
for (int i = 0; i < nEdges; i++) {
56+
int u, v, w;
57+
cin >> u >> v >> w;
58+
59+
g->insertEdge(u, v, w);
60+
}
61+
}
62+
63+
64+
// N[i][j] : i에서 출발해 탬색 범위 내의 j에서 얻을 수 있는 아이템 수
65+
int solve(Graph* g, int range) {
66+
int** A = new int*[(g->n) + 1];
67+
int** N = new int* [(g->n) + 1];
68+
69+
for (int i = 0; i < g->n + 1; i++) {
70+
A[i] = new int[(g->n) + 1];
71+
N[i] = new int[(g->n) + 1];
72+
}
73+
74+
// 기본값 A에서 자신에 대해 0, 아닌경우는 INF로 초기화 하고
75+
for (int i = 0; i < g->n + 1; i++) {
76+
for (int j = 0; j < g->n + 1; j++) {
77+
N[i][j] = 0;
78+
if (i == j) {
79+
A[i][j] = 0;
80+
}
81+
else {
82+
A[i][j] = INF;
83+
}
84+
}
85+
}
86+
87+
// 처음 알 수 있는 인접정점에 대해 A를 업데이트 한다.
88+
for (int i = 0; i < g->n + 1; i++) {
89+
N[i][i] = g->nItems[i];
90+
91+
int s = g->adj[i].size();
92+
for (int j = 0; j < s; j++) {
93+
pair<int, int> v = g->adj[i][j];
94+
95+
// 인접 정점이 탐색 범위 내에 있는 경우만
96+
if (v.second <= range) {
97+
A[i][v.first] = v.second;
98+
N[i][v.first] = g->nItems[v.first];
99+
}
100+
}
101+
}
102+
103+
104+
// Floyd Warshall
105+
for (int k = 0; k < g->n + 1; k++) {
106+
for (int i = 0; i < g->n + 1; i++) {
107+
for (int j = 0; j < g->n + 1; j++) {
108+
int newPath = A[i][k] + A[k][j];
109+
// 새로 구해진 정점 k를 거쳐 가는 최단 거리가 탐색 범위 내인 경우만
110+
if (newPath < A[i][j] && newPath <= range) {
111+
A[i][j] = newPath; // A 업데이트
112+
N[i][j] = g->nItems[j]; // i에서 출발했을때 j에서 얻는 아이템수
113+
}
114+
}
115+
}
116+
}
117+
118+
119+
// i에서 출발한 탐색범위 내의 j에서 얻을 수 있는 아이템수를 다 더한다.
120+
// 그후 가장 많이 얻을 수 있는 아이템의 수를 찾는다.
121+
int res = -0x7fffffff;
122+
for (int i = 0; i < g->n + 1; i++) {
123+
int sum = 0;
124+
125+
// 정점 i시작 한 경우 얻을 수 있는 아이템수 합
126+
for (int j = 0; j < g->n + 1; j++) {
127+
if (N[i][j] != 0) {
128+
sum += N[i][j];
129+
}
130+
}
131+
132+
// 가장 큰 값을 찾는다.
133+
res = max(res, sum);
134+
}
135+
136+
// 결과 res
137+
return res;
138+
}
139+
140+
141+
int main(void) {
142+
ios::sync_with_stdio(false);
143+
cin.tie(0); cout.tie(0);
144+
145+
// 정점 수, 탐색 범위, 간선 수 입력
146+
int nVertices, range, nEdges;
147+
cin >> nVertices >> range >> nEdges;
148+
149+
// 그래프 생성
150+
Graph* g = new Graph(nVertices);
151+
152+
// 입력
153+
input(g, nVertices, nEdges);
154+
155+
// 결과 출력
156+
cout << solve(g, range);
157+
158+
return 0;
159+
}
160+
```

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /