1.递归方程
dij(k)=wij(k = 0), min(dij(k-1), dik(k-1)+dkj(k-1)(k>=1)
2.程序
/************************************ **Algorithm: Floyd (With Direction) *************************************/ #include <iostream> using namespace std; const int MAXV = 100; //The number of vertexs const int MAX = 1 << 28; //Don't make it too big as we use addition int map[MAXV][MAXV], dis[MAXV][MAXV], pi[MAXV][MAXV];//map record the direct distance, dis record the minest distance int len, ans[MAXV]; int n, m, u, v, w;//n denotes the number of vertexs, m denotes the number of edges int main() { scanf("%d%d", &n, &m); //INITIALIZE for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (i == j) map[i][j] = 0; else map[i][j] = MAX; //READ THE EDGE for (int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &w); if (w < map[u][v]) map[u][v] = w;//map[u][v] = map[v][u] = w; } //INITIALIZE for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { dis[i][j] = map[i][j]; if (dis[i][j] != MAX) pi[i][j] = i; else pi[i][j] = 0; } //FLOYED-WARSHALL for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (dis[i][k]+dis[k][j] < dis[i][j]) { dis[i][j] = dis[i][k] + dis[k][j]; pi[i][j] = pi[k][j]; } //PRINT THE SHORTEST DISTANCES printf("Please input the vertexs to show the SP:"); scanf("%d %d", &u, &v); len = 0; while (u != v) { ans[len++] = v; v = pi[u][v]; } ans[len++] = u; for (int i = len-1; i >= 0; i--) printf("%d/n", ans[i]);//NOTE that print in the reverse order return 0; }
3.应用:
1.求最小环USACO4.1.3
具体的程序见USACO专题,基本的代码如下:
/************************************************************ **Algorithm: Floyd (With direction) to get the minimal cycle *************************************************************/ #include <iostream> using namespace std; const int MAXV = 100; //The number of vertexs const int MAX = 1 << 28; //Don't make it too big as we use addition int map[MAXV][MAXV], dis[MAXV][MAXV], pi[MAXV][MAXV];//map record the direct distance, dis record the minest distance int min_cycle, len, ans[MAXV]; int n, m, u, v, w;//n denotes the number of vertexs, m denotes the number of edges void recordpath(int i, int j, int k) {//i -> j -> k len = 0; while (j != i) { ans[len++] = j; j = pi[i][j]; } ans[len++] = i; ans[len++] = k; } int main() { scanf("%d%d", &n, &m); //INITIALIZE for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (i == j) map[i][j] = 0; else map[i][j] = MAX; //READ THE EDGE for (int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &w); if (w < map[u][v]) map[u][v] = w;//map[u][v] = map[v][u] = w; } //INITIALIZE for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { dis[i][j] = map[i][j]; if (dis[i][j] != MAX) pi[i][j] = i; else pi[i][j] = 0; } //FLOYED-WARSHALL min_cycle = MAX; for (int k = 1; k <= n; k++) { for (int i = 1; i < k; i++) if (map[k][i] < MAX) for (int j = 1; j < k; j++) if (map[j][k] < MAX && dis[i][j] + map[j][k] + map[k][i] < min_cycle) { min_cycle = dis[i][j] + map[j][k] + map[k][i]; recordpath(i, j, k); } for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (dis[i][k]+dis[k][j] < dis[i][j]) { dis[i][j] = dis[i][k] + dis[k][j]; pi[i][j] = pi[k][j]; } } //PRINT THE SHORTEST DISTANCES printf("The minimal cycle: %d/nThe vertex on the cycle: %d/n", min_cycle, len); for (int i = len-1; i >= 0; i--) printf("%d/n", ans[i]); return 0; }
2.URAL 1004