#include #define MAXM 32 #define INF 0x3F000000 int mx, my; char map[MAXM][MAXM]; typedef int vals_t [MAXM][MAXM]; vals_t srcpath, dstpath, srcdist, dstdist; double load [MAXM][MAXM]; int plus (int a, int b) { return (a + b > INF) ? INF : a + b; } int qx[MAXM*MAXM], qy[MAXM*MAXM], qb, qe; void enqueue (int x, int y, int d, int p, vals_t *dist, vals_t *path, char dst) { if ( map[x][y] != '.' && map[x][y] != dst ) return; if ( (*dist)[x][y] < 0 ) { (*dist)[x][y] = d; (*path)[x][y] = p; qx[qe] = x; qy[qe++] = y; return; } else if ( (*dist)[x][y] == d ) (*path)[x][y] = plus ((*path)[x][y], p); } void findpath (char src, char dst, vals_t *dist, vals_t *path, int *px, int *py) { int i, j, x, y, d, p; for ( i = 0; i < mx; ++i ) for ( j = 0; j < my; ++j ) { (*dist)[i][j] = -1; if ( map[i][j] == src ) { *px = qx[0] = x = i; *py = qy[0] = y = j; } } (*dist)[x][y] = 0; (*path)[x][y] = 1; qb = 0; qe = 1; while ( qb < qe ) { x = qx[qb]; y = qy[qb++]; d = (*dist)[x][y] + 1; p = (*path)[x][y]; if ( x > 0 ) enqueue (x-1, y, d, p, dist, path, dst); if ( x < mx-1 ) enqueue (x+1, y, d, p, dist, path, dst); if ( y > 0 ) enqueue (x, y-1, d, p, dist, path, dst); if ( y < my-1 ) enqueue (x, y+1, d, p, dist, path, dst); } } int main (void) { int i, j, ld, pthlen, pthcnt, sx, sy, dx, dy; char sch, dch; for ( ; ; ) { scanf ("%d%d\n", &my, &mx); if ( !mx || !my ) break; for ( i = 0; i < mx; ++i ) scanf ("%s\n", map[i]); for ( i = 0; i < mx; ++i ) for ( j = 0; j < my; ++j ) load[i][j] = 0.0; for ( ; ; ) { scanf ("%c%c %d\n", &sch, &dch, &ld); if ( sch == 'X' || dch == 'X' ) break; findpath (sch, dch, &srcdist, &srcpath, &sx, &sy); findpath (dch, sch, &dstdist, &dstpath, &dx, &dy); pthlen = srcdist[dx][dy]; pthcnt = srcpath[dx][dy]; for ( i = 0; i < mx; ++i ) for ( j = 0; j < my; ++j ) if ( map[i][j] == '.' && srcdist[i][j] + dstdist[i][j] == pthlen ) load[i][j] += ld * 1.0 * srcpath[i][j] * dstpath[i][j] / pthcnt; } for ( i = 0; i < mx; ++i ) for ( j = 0; j < my; ++j ) printf ("%6.2f%c", load[i][j], (j==my-1) ? '\n' : ' '); } return 0; }