题意本不错,建图过程比前面几个题复杂,但是输入数据格式实在是猥琐。
非得字符串,然后还空格。。
开始用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;
}