Overfencing

题意:有一个W*H大小的迷宫,迷宫有两个出口,并且从迷宫中的每一个点都能够找到出口出去。求从迷宫中任意一点走出去的最优路线长度的最大值


解题思路

  1. 读入W、H以及迷宫形状(用字符串数组maze[i][j]保存)
  2. 根据maze,用邻接表table[i][j]来表示这个迷宫。table[i][j] = k,代表节点i的第j个邻节点是k。并且在读取过程中保存两个出口所在的节点
  3. 对这两个出口节点进行Dijkstra,可以得到从出口到每一个节点的最短路径,分别保存为distance[i]和distance_cp[i]两个数组,distance[i] = j,代表从出口到i节点的最短路径长度为j
  4. 对distance和distance_cp两个数组遍历一遍即可得到最优线路的最大值

代码

/*
ID: zc.rene1
LANG: C
PROG: maze1
*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int W, H;
char **maze;
int **table;
int exits[2] = {0, 0};
int exits_count = 0;
int *distance = NULL;

int GetLeastUnvisited(int *visited, int *distance)
{
    int i, ret = -1, least_distance = W*H;

    for (i=0; i<W*H; i++)
    {
	if (visited[i] == 0)
	{
	    if (distance[i] < least_distance)
	    {
		ret = i;
		least_distance = distance[i];
	    }
	}
    }
    return ret;
}

void Dijkstra(int source)
{
    int *visited;
    int i, current_node, neighbour;
    int temp, ret = 0;

    visited = (int *)malloc(W*H*sizeof(int));

    memset(visited, 0, W*H*sizeof(int));
    for (i=0; i<W*H; i++)
    {
	distance[i] = W*H;
    }
    distance[source] = 0;

    while ((current_node = GetLeastUnvisited(visited, distance)) != -1)
    {
	visited[current_node] = 1;
	i = 0;
	while ((neighbour = table[current_node][i]) != -1)
	{
	    if (!visited[neighbour])
	    {	    
		if ((distance[current_node] + 1) < distance[neighbour])
		{
		    distance[neighbour] = distance[current_node] + 1;
		}
	    }
	    i++;
	    if (i > 3)
	    {
		break;
	    }
	}
    }
}

void InsertNeighbour(int add_i, int add_j, int addto_i, int addto_j)
{
    int add = add_i * W + add_j;
    int add_to = addto_i * W + addto_j;
    int temp = 0;

    if ((add_i < 0)||(add_i >= H))
    {
	exits[exits_count++] = add_to;
    }
    else if ((add_j < 0)||(add_j >= W))
    {
	exits[exits_count++] = add_to;
    }
    else
    {
	while (table[add_to][temp] != -1)
	{
	    temp++;
	}
	table[add_to][temp] = add;
    }
}

void AddNeighbour(int i, int j)
{
    int room_i = 2 * i + 1;
    int room_j = 2 * j + 1;

    if (maze[room_i-1][room_j] == ' ')
    {
	InsertNeighbour(i-1, j, i, j);
    }
    if (maze[room_i+1][room_j] == ' ')
    {
	InsertNeighbour(i+1, j, i, j);
    }
    if (maze[room_i][room_j-1] == ' ')
    {
	InsertNeighbour(i, j-1, i, j);
    }
    if (maze[room_i][room_j+1] == ' ')
    {
	InsertNeighbour(i, j+1, i, j);
    }
}

int main(void)
{
    FILE *fin, *fout;
    int i, j, temp, result = 0;
    char c;

    fin = fopen("maze1.in", "r");
    fout = fopen("maze1.out", "w");

    fscanf(fin, "%d %d", &W, &H);

    table = (int **)malloc(W*H*sizeof(int*));
    for (i=0; i<W*H; i++)
    {
	table[i] = (int *)malloc(4*sizeof(int));
	memset(table[i], -1, 4*sizeof(int));
    }

    maze = (char **)malloc((2*H+1)*sizeof(char *));
    for (i=0; i<2*H+1; i++)
    {
	maze[i] = (char *)malloc((2*W+1)*sizeof(char));
	memset(maze[i], 0, (2*W+1)*sizeof(char));
    }

    fscanf(fin, "%c", &c);
    for (i=0; i<2*H+1; i++)
    {
	for (j=0; j<2*W+1; j++)
	{
	    fscanf(fin, "%c", &maze[i][j]);
	}
	fscanf(fin, "%c", &c);
    }

    for (i=0; i<H; i++)
    {
	for (j=0; j<W; j++)
	{
	    AddNeighbour(i, j);
	}
    }

    distance = (int *)malloc(W*H*sizeof(int));
    Dijkstra(exits[0]);
    int *distance_cp = (int *)malloc(W*H*sizeof(int));
    memcpy(distance_cp, distance, W*H*sizeof(int));

    Dijkstra(exits[1]);

    for (i=0; i<W*H; i++)
    {
	temp = (distance[i] < distance_cp[i] ? distance[i] : distance_cp[i]);
	if (temp > result)
	{
	    result = temp;
	}
    }

    fprintf(fout, "%d\n", result + 1);
    return 0;
}
























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值