—— by A Code Rabbit
Description
一张有20个顶点的图上。
依次输入每个点与哪些点直接相连。
并且多次询问两点间,最短需要经过几条路才能从一点到达另一点。
Type
Graph Algorithms
Analysis
询问数较多,是经典的 Floyd求任意两点间的最短路径长度。
利用Floyd解题,初始化领接矩阵的时候要注意,可以将没有直接相连的两点之间定义为一个较大的值。
但是要注意,Floyd需要将两数相加,因此这个值不能大于int上限的一半。
Solution
// UVaOJ 567 // Risk // by A Code Rabbit #include <cstdio> #include <cstring> const int N = 20; const int MAXV = 22; const int INF = 1e9; template <typename T> struct Graph { T mat[MAXV][MAXV]; void Init(int n) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { mat[i][j] = i == j ? 0 : INF; } } } void AddEdge(int u, int v, T w) { mat[u][v] = w; } }; namespace Floyd { template <typename T> void Go(T w[MAXV][MAXV], int n) { for (int k = 0; k < n; k++) for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) if (w[i][k] + w[k][j] < w[i][j]) w[i][j] = w[i][k] + w[k][j]; } } int n; int a, b; Graph<int> graph; void Read(int x, int num); int main() { int tot_case = 0; while (scanf("%d", &n) != EOF) { // Input. graph.Init(N); Read(0, n); for (int i = 1; i < N - 1; i++) { scanf("%d", &n); Read(i, n); } // Solve. Floyd::Go(graph.mat, N); // Output. printf("Test Set #%d\n", ++tot_case); scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d%d", &a, &b); printf("%2d to %2d: %d\n", a, b, graph.mat[a - 1][b - 1]); } printf("\n"); } return 0; } void Read(int x, int num) { for (int i = 0; i < num; i++) { int y; scanf("%d", &y); graph.AddEdge(x, y - 1, 1); graph.AddEdge(y - 1, x, 1); } }