一、题意
每组数据有20个城市,给出每个城市与之相邻的城市,距离为1,不相邻的城市认为不可达。然后有q个询问,每次询问任意两个城市之间的距离。
二、解析
由于要询问任意两个城市之间的距离,因此这是一个多源最短路问题,即需要得到每两个点之间的最短路。这样的问题只能使用Floyd算法。算法复杂度为O(n^3),在数据量小的时候非常方便。
PS: 这题的输入搞得相当复杂orz....我主要是想复习一下Floyd的模板而已....
三、代码
#include <iostream> #include <iomanip> #include <cmath> using namespace std; const int n = 20, INF = 1 << 29; int kase = 1, q, d[n + 1][n + 1]; bool read(istream& in) { for(int i = 1; i <= n; i ++) { // 初始化d for(int j = 1; j <= n; j ++) d[i][j] = INF; d[i][i] = 0; } for(int u = 1, m, v; u < n; u ++) { if(!(in >> m)) return 0; while(m --) in >> v, d[u][v] = d[v][u] = 1; } return 1; } void Floyd() { for(int k = 1; k <= n; k ++) { // 枚举中间点 for(int i = 1; i <= n; i ++) { for(int j = 1; j <= n; j ++) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } } int main() { while(read(cin)) { Floyd(); cin >> q; cout << "Test Set #" << kase ++ << "\n"; while(q --) { int u, v; cin >> u >> v; cout << setw(2) << u << " to " << setw(2) << v << ": " << d[u][v] << "\n"; } cout << endl; } }
四、归纳
- Floyd算法用于处理多源最短路问题,正权负权均可处理,需要使用邻接矩阵来存放点距,大致模板如下:
const int INF = 1 << 29; int n, d[maxn][maxn]; void init() { for(int i = 1; i <= n; i ++) { // 初始化d for(int j = 1; j <= n; j ++) d[i][j] = INF; d[i][i] = 0; } } void Floyd() { for(int k = 1; k <= n; k ++) { // 枚举中间点 for(int i = 1; i <= n; i ++) { for(int j = 1; j <= n; j ++) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } } int main() { ...... init(); Floyd(); ...... }
- 要注意Floyd中会有INF相加的情况,因此INF值不能太大,这里取的是1<<29.