hdu 3631 Shortest Path (floyd)

来源:互联网 发布:上海好的java培训机构 编辑:程序博客网 时间:2024/04/29 21:39

n个点从0 , 1, 2 ,3.....n-1,这些点只有被标记过之后才能走,求给出的两点之间的最短路。

Floyd的思想拿来插点。很容易想到两种更新两点之间距离的大概思路:

1:给出的两点X,Y,遍历所有点看是否能够松弛,即dis【X】【Y】 = MIN(dis【x】【i】 + dis【i】【Y】)。

2:对每次给出的新的标记的点Z,以其为松弛点遍历整张图里的点对之间距离,即dis【i】【j】 = MIN(dis【i】【Z】, dis【Z】【j】)。

但实际上第一种更新是错的,因为只松弛了i的点而其他点对之间还没有松弛。第二种的时间是O(N^2*K)

#include<stdio.h>#include<string.h>#include<string.h>#include<algorithm>#include<queue>using namespace std;const int N = 305;const int inf = 1 << 28;int a[N][N];int used[N], vis[N], dis[N];int n, m, k;void init(){for( int i = 0; i <= n; i++ ){used[i] = vis[i] = 0;dis[i] = inf;for( int j = 0; j <= n; j++ ){a[i][j] = (i == j? 0: inf);}}}void floyd(int mid){for( int i = 0; i < n; i++ ){for( int j = 0; j < n; j++ ){a[i][j] = min(a[i][j], a[i][mid] + a[mid][j]);}}}int main(){int cas = 1;while(~scanf("%d%d%d", &n, &m, &k) && (n || m || k)){init();int u, v, w;while(m--){scanf("%d%d%d", &u, &v, &w);a[u][v] = min(a[u][v], w);}int x, y, z;//floyd();if( cas > 1 )puts("");printf("Case %d:\n", cas++);while(k--){int op;scanf("%d", &op);if( op == 1 ){scanf("%d%d", &x, &y);if( !used[x] || !used[y] ){printf("ERROR! At path %d to %d\n", x, y);continue;}if( a[x][y] < inf )printf("%d\n", a[x][y]);elseputs("No such path");}else{scanf("%d", &z);if( used[z] )printf("ERROR! At point %d\n", z);else{used[z] = 1;floyd(z);}}}}return 0;}


0 0
原创粉丝点击