반응형
https://www.acmicpc.net/problem/1507
1507번: 궁금한 민호
강호는 N개의 도시로 이루어진 나라에 살고 있다. 각 도시는 M개의 도로로 연결되어 있으며, 각 도로를 지날 때 필요한 시간이 존재한다. 도로는 잘 연결되어 있기 때문에, 도시 A에서 B로 이동할 수 없는 경우는 존재하지 않는다. 도시 A에서 도시 B로 바로 갈 수 있는 도로가 있거나, 다른 도시를 거쳐서 갈 수 있을 때, 도시 A에서 B를 갈 수 있다고 한다. 강호는 모든 쌍의 도시에 대해서 최소 이동 시간을 구해놓았다. 민호는 이 표를 보고 원래 도로
www.acmicpc.net
문제에 주어진 값들이 플로이드 와샬을 거친값이라는 것을 안다면 접근이 쉬워진다.
만약 주어진값이 와샬이 아니라면 최소의 간선으로 최소비용을 만들수 없으므로 -1을 출력한다.
주어진 값이 와샬이맞다면 현재 와샬로 그을수있는 모든 노드의 가중치를 긋고
와샬 dp[i][j] == dp[i][k] +dp[k][j] 를 만족하는 i -- j 간선을 지워주면 된다.
이것이 왜가능한지를 생각해보면 와샬이전에 실제 노드에 대해서는 생각할 필요가없다.
와샬값으로 이전의 간선을 추리한다는것은 불가능하고 여기선 이 와샬필드를 가지고 최소로 만드는것에 주목해야한다.
그렇다면 와샬필드를가지고 N*(N-1) 개의 간선들을 이을수있다. 여기서 와샬을 만족한다면 모든필드에대해서
dp[i][j] <= dp[i][k] +dp[k][j] 를 만족한다 만약 두값이 같다면 i - j 간석을 지워도된다 왜냐면 i -k -j 로 가는 간선이 존재하기때문에 와샬을 바뀌지않는다
ps) 결론 : 와샬을 필드의 값들을 헤치지않으면서 간선들을 지울 수 있는것을 모두지우면 그것이 최소간선이다.
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
package algo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class B1507 {
static int N;
static int edge[][];
static int dp[][];
static final int INF = 987654321;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
N = Integer.parseInt(br.readLine());
edge = new int[N][N];
dp = new int[N][N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
edge[i][j] = Integer.parseInt(st.nextToken());
dp[i][j] = edge[i][j];
}
}
boolean isPossible = true;
for (int k = 0; k < N; k++) {
for (int i = 0; i < N; i++) {
if (i == k)
continue;
for (int j = 0; j < N; j++) {
if (i == j || j == k)
continue;
if (dp[i][j] > dp[i][k] + dp[k][j]) {
isPossible = false;
break;
} else if(dp[i][j] == dp[i][k] + dp[k][j]){
edge[i][j] = 0;
}
}
if (!isPossible)
break;
}
if (!isPossible)
break;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
System.out.print(edge[i][j]+" ");
}
System.out.println();
}
System.out.println();
if (isPossible) {
int sum = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (edge[i][j] == 0)
continue;
sum += edge[i][j];
edge[i][j] = 0;
edge[j][i] = 0;
}
}
System.out.println(sum);
} else {
System.out.println(-1);
}
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
반응형