題目簡述

  • 現在有多個人,任意兩個人可能有直接關係,或是沒有直接關係
  • 依序輸入兩個人的名字,代表這兩個人是有直接關係的
  • 要求輸出最大有幾度分隔(maximum degree of separation)(任意選兩個人,他們的間隔一定會不大於輸出的答案)
  • 若是可以找到兩個人中間沒有間隔(就是沒有間接關係),輸出”DISCONNECTED”

    解題想法

  • 這是一題 All-Pairs Shortest Path 的題目
  • 使用 Floyd-Warshall 演算法來解題
  • Floyd-Warshall 演算法
    • $$D_{i, j, k-1}=min
      \begin{cases}
      D_{i, j, k-1}\\
      D_{i, k, k-1}+D_{k, j, k-1}
      \end{cases}$$
    • 當要從點 i 走到點 j 時,要不就是從 i 走到 j, i → j ,要不就是經過一個點 k, i → k → j
    • 這個演算法主要是用三層迴圈實作
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      /* Floyd-Warshall Algorithm */
      for(int k = 0; k < P; ++k){
      for(int i = 0; i < P; ++i){
      for(int j = 0; j < P; ++j){
      int dis = remap[i][k] + remap[k][j];
      if(dis < remap[i][j] && i != j && i != k && j != k){
      remap[i][j] = dis;
      remap[j][i] = dis;
      }
      }
      }
      }
    • 最外層的 k 是掃過所有的中繼點,然後分別掃描每個點 i 到點 j 的距離
    • 最裡面的 dis 先計算 i → k → j 的距離,然後和原本 i → j 的距離比較,選較小的那個存起來

程式碼

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
/*****************************************
Filename:p1056.cpp
Author:Willy Chen(willychen.org)
Date:2019.09.19
*****************************************/
#include<iostream>
#include<string>
#include<map>
using namespace std;

int main(){
int P, R;
int kase = 0;
while(1){
cin >> P >> R;
if(P == 0 && R == 0){
break;
}
string name1, name2;
int ids = 0;
map<string, int> name2id;
int remap[50][50] = {0};
for(int i = 0; i < 50; ++i)
for(int j = 0; j < 50; ++j)
remap[i][j] = 100000;

/* Read relations and create graph */
for(int i = 0; i < R; ++i){
cin >> name1 >> name2;
int id1, id2;
map<string, int>::iterator re = name2id.find(name1);
if(re == name2id.end()){
name2id[name1] = ids++;
}
id1 = name2id[name1];
re = name2id.find(name2);
if(re == name2id.end()){
name2id[name2] = ids++;
}
id2 = name2id[name2];

/* Create adjacency matrix */
remap[id1][id2] = 1;
remap[id2][id1] = 1;
}
/* Floyd-Warshall Algorithm */
for(int k = 0; k < P; ++k){
for(int i = 0; i < P; ++i){
for(int j = 0; j < P; ++j){
int dis = remap[i][k] + remap[k][j];
if(dis < remap[i][j] && i != j && i != k && j != k){
remap[i][j] = dis;
remap[j][i] = dis;
}
}
}
}
int ans = 0;
/* Get the maximum value */
for(int i = 0; i < P; ++i){
for(int j = 0; j < P; ++j){
if(i != j && remap[i][j] == 100000){
ans = -1;
continue;
}
if(remap[i][j] != 100000 && ans != -1 && ans < remap[i][j]){
ans = remap[i][j];
}
}
}
kase++;
if(ans == -1){
printf("Network %d: DISCONNECTED\n\n", kase);
}else{
printf("Network %d: %d\n\n", kase, ans);
}
}
return 0;
}

評論

 無法加載Disqus評論系統,請確保您的網絡能夠正常訪問。



本站使用 Volantis 作為主題