poj 3026 迷宫探索外星人

题意本不错,建图过程比前面几个题复杂,但是输入数据格式实在是猥琐。

非得字符串,然后还空格。。

开始用scanf() getchar() WA了一次,后来看了别人的改成cin gets(),

建图是关键:如何通过不同结点建立邻接矩阵,采用广度优先遍历,从字母结点遍历到其他各个字母结点的路径(原题

中说不计算走回的路径,就是为了建图的时候各个点互相不干扰)

#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <cctype>
#include <algorithm>
#include <cmath>
#include <deque>
#include <queue>
#include <map>
#include <queue>
#include <list>
#include <iomanip>
using namespace std;                                               
///
///
const int INF =  20000000;   
#define maxn 55   
#define max(a,b)(a>b?a:b)
///
int testcases;//测试数目
int col, row;
char maze[maxn][maxn];
int mark[maxn][maxn];//记录当前坐标是否为字母,第几个字母
int dist[110][110];
int edge[110][110];
int num;//字母的个数
struct pos{
	int y;
	int x;
}mov[4]={{0,-1},{0,1},{-1,0},{1,0}};
int lowc[110];
void bfs(int yy, int xx)
{
	bool vis[110][110];
	memset(vis, false, sizeof(vis));

	memset(dist, 0, sizeof(dist));
	vis[yy][xx] = true;
	queue<pos> stk;
	while (!stk.empty())
		stk.pop();

	pos startpos;
	startpos.y = yy;
	startpos.x = xx;
	stk.push(startpos);
	while (!stk.empty())
	{
		pos tempPos = stk.front();
		stk.pop();
		if (mark[tempPos.y][tempPos.x])
			edge[mark[yy][xx]][mark[tempPos.y][tempPos.x]] = dist[tempPos.y][tempPos.x];
		for (int k = 0; k < 4; k++)
		{
			pos newpos;
			int newy = newpos.y = tempPos.y + mov[k].y;
			int newx = newpos.x = tempPos.x + mov[k].x;
			if (newy >= 1 && newy <= row && newx >= 1 && newx <= col)
			{
				if (!vis[newy][newx] && maze[newy][newx] != '#')
				{
					stk.push(newpos);
					vis[newy][newx] = true;
					dist[newy][newx] = dist[tempPos.y][tempPos.x] + 1;
				}
			}
		}
	}
}
int prim()
{
	int i, j;
	int minc, res = 0;
	int p;
	bool vis[110];
	memset(vis, false, sizeof(vis));

	vis[1] = true;
	for (i = 2; i <= num; i++)
		lowc[i] = edge[1][i];

	for (i = 2; i <= num; i++)
	{
		minc = INF;
		p = -1;
		for (j = 1; j <= num; j++)
		{
			if (0 == vis[j] && minc > lowc[j])
			{
				minc = lowc[j];
				p = j;
			}
		}
		res += minc;
		vis[p] = true;
		for (j = 1; j <= num; j++)
		{
			if (0 == vis[j] && lowc[j] > edge[p][j])
				lowc[j] = edge[p][j];
		}
	}
	return res;
}
int main()
{
	freopen("F:\\input.txt","r",stdin );
	///
	int i, j;
	cin >> testcases;
	while (testcases--)
	{
		//初始化
		memset(mark, 0, sizeof(mark));
		num = 0;
		memset(maze, 0, sizeof(maze));
		//第一步建图
		cin >> col >> row;
		char temp[51];
		gets(temp);  //吃掉cin遗留下来的换行符,我不知道为什么getchar()会AW 
		for (i = 1; i <= row; i++)
		{
//			while (i != row && getchar() != '\n');//输入数据太猥琐了!!
			gets(maze[i] + 1);
			for (j = 1; j <= col; j++)
			{
//				maze[i][j] = getchar();
				if (maze[i][j] == 'A' || maze[i][j] == 'S')
					mark[i][j] = ++num;
			}
		}
		for (i = 1; i <= row; i++)
		{
			for (j = 1; j <= col; j++)
			{
				if (mark[i][j])
					bfs(i, j);
			}
		}
		int ans = prim();
//		cout << endl;
		cout << ans << endl;
	}
	///
    return 0;
}                                              



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值