http://acm.pku.edu.cn/JudgeOnline/problem?id=1124

Код:
#include <stdio.h>
#define UP 1
#define DOWN 2
#define RIGHT 3
#define LEFT 4

#define MAX_PATHS 50000

int rows;
int columns;

char map[25][25];
double loads[25][25];
char inputline[100];
int doorx[30];
int doory[30];


int start; 
int finish;
int load;
int paths[MAX_PATHS][100];
int current_path[500];
int travelled[25][25];
int num_paths;
int min_path;

void copy_path(int steps, int number)
{
	int x;

	if (number > MAX_PATHS)
	{
	    num_paths++;
return;

printf("Resetting the minimum to %d\n", min_path);
num_paths = 0;
min_path = min_path - 1;
return;
	}

	for (x = 0; x < steps; x++)
	{
paths[number][x] = current_path[x];
//printf("Copying path %d step %d value %d\n", number, x, current_path[x]);
	}
	num_paths = number + 1;
}


void check_path(int sx, int sy, int fx, int fy, int step)
{
	if ((sx == fx) && (sy == fy))
	{
//printf("Found path %d %d %d %d %d %d\n", sx, sy, fx, fy, step, num_paths);
if (step < min_path)
{
	min_path = step;
	copy_path(step, 0);
}
else if (step == min_path) copy_path(step, num_paths);
return;
	}

	// If I have been here, it is not a sidewalk, I have reached the minimum path, or it is not a valid space return
	if (travelled[sx][sy] != 0) return;
	if ((map[sx][sy] != '.') && (step != 0)) return;
	if (step >= min_path) return;
	if ((sx < 0) || (sy < 0) || (sx == rows) || (sy == columns)) return;

travelled[sx][sy] = step;
	if (sx < fx)
	{ /* check down then up */
current_path[step] = DOWN;
check_path(sx+1, sy, fx, fy, step + 1);
current_path[step] = UP;
check_path(sx-1, sy, fx, fy, step + 1);
	}
	else 
	{ /* check down then up */
current_path[step] = UP;
check_path(sx-1, sy, fx, fy, step + 1);
current_path[step] = DOWN;
check_path(sx+1, sy, fx, fy, step + 1);
	}
	if (sy < fy)
	{
current_path[step] = RIGHT;
check_path(sx, sy+1, fx, fy, step + 1);
current_path[step] = LEFT;
check_path(sx, sy-1, fx, fy, step + 1);
	}
	else 
	{
current_path[step] = LEFT;
check_path(sx, sy-1, fx, fy, step + 1);
current_path[step] = RIGHT;
check_path(sx, sy+1, fx, fy, step + 1);
	}
	travelled[sx][sy] = 0;
	return;
}

void add_paths(int x, int y, int fx, int fy, double per)
{
	int cx, cy;
	int i, j;
if (num_paths > MAX_PATHS)
{ 
printf("Ran out of space %d %d %d %d %d\n", x, y, fx, fy, num_paths);
return;
}
//printf("Adding paths %d %d %d %d %lf\n", x, y, num_paths, min_path, per);
	for (j = 0; j < num_paths; j++)
	{
cx = x; cy = y;

for (i = 0; i < (min_path-1); i++)
{
//printf("Adding to %d %d value %lf\n", cx, cy, per);
	switch (paths[j][i])
	{
case UP: cx = cx-1; break;
case DOWN: cx = cx+1; break;
case RIGHT: cy = cy+1; break;
case LEFT: cy = cy-1; break;
	}
	loads[cx][cy] += per;
}
	}
}

void add_load(int s, int f, int l)
{
	int x, y;
	int myx, myy;
	int fx, fy;
	double per;
//printf("Adding load %d %d %d\n", s,f,l); 

	num_paths = 0;
	min_path = 60;

	for (x = 0; x < rows; x++)
for (y = 0; y < columns; y++)
	travelled[x][y] = 0;

	myx = doorx[s];
	myy = doory[s];

	fx = doorx[f];
	fy = doory[f];

//printf("Path search for %d %d to %d %d\n", myx, myy, fx, fy);

	check_path(myx, myy, fx, fy, 0);

	per = (double)load / num_paths;

	add_paths(myx, myy, fx, fy, per);

 // printf("Adding load from %d %d to %d %d of size %d %lf %d\n", myx, myy, fx, fy, l, per, num_paths);
}

void print_loads(void)
{
	int x, y;

	for (x = 0; x < rows; x++)
	{
for (y = 0; y < columns; y++)
{
	printf("%7.2lf", loads[x][y]);
}
printf("\n");
	}
}


int main(void){
	int x,y;

	gets(inputline);
	sscanf(inputline, "%d %d", &columns, &rows);

	for (x = 0; x < rows; x++)
	{
gets(inputline);
for (y = 0; y < columns; y++)
{
	loads[x][y] = 0;
	map[x][y] = inputline[y];
	if ((inputline[y] != '.') && (inputline[y] != 'X'))
	{
doorx[inputline[y] - 'A'] = x;
doory[inputline[y] - 'A'] = y;
	}
}
	}
#if 0
	for (x = 0; x < rows; x++)
	{
for (y = 0; y < columns; y++)
{
	printf("%7.2lf", loads[x][y]);
}
printf("\n");
	}

	for (x = 0; x < rows; x++)
	{
for (y = 0; y < columns; y++)
{
	printf("%c", map[x][y]);
}
printf("\n");
	}
#endif 
	gets(inputline);
	while (inputline[0] != 'X')	
	{
sscanf(&(inputline[2]), "%d",&load);
start = inputline[0]-'A';
finish = inputline[1]-'A';
add_load(start, finish, load);
gets(inputline);
	}

	print_loads();
}