题目说明:
这道题槽点太多,除了discuss里的输入数据的问题,自己犯的错误是一直TLE,不得不考虑降低复杂度,由原来的n^2/2 * O(bfs) 降到 n * O(bfs) 。
改进前:相当于对任意两点算一次BFS:有n个点自然算n^2次BFS
<span style="font-size:18px;">void constructGraph(int num,int target[][2])
{
for (int i = 1; i <= num; i++)
{
for (int j = 1; j <= num; j++)
{
//calculate the value between target[i] ---> target[j]
if (graph[i][j]==-1)
graph[i][j]=graph[j][i] = bfs(i-1,j-1,target);
}
}
}</span>
改进后:对每个点算一次BFS,这一次直接算到底,这个点和其他所有点的distance都算出,自然是算n次BFS。
void constructGraph(int num,int target[][2])
{
for (int i = 0; i<num; i++)
{
bfs(target,i);
for (int j = 0; j<num; j++)
graph[i+1][j+1] = dist[target[j][0]][target[j][1]];
}
}
完整代码:
#include<iostream>
#include<fstream>
#include<queue>
using namespace std;
const int MAX = 102;
const int MAXCOST = 0x7fffffff;
int graph[MAX][MAX], dist[MAX][MAX];
char map[MAX][MAX];
int num,row, col;
int dir[4][2] = {
0, -1, //up
0, 1, //down
-1, 0, //left
1, 0, //right
};
struct Node{
int x, y;
};
int prim(int graph[][MAX], int n)
{
int sum=0;
int lowcost[MAX];
int mst[MAX];
for (int i = 1; i <= n; i++)
{
lowcost[i] = graph[1][i];
mst[i] = 1;
}
mst[1] = 0;
for (int i = 1; i <= n - 1; i++)
{
int min=MAXCOST, minid=0;
for (int j = 2; j <= n; j++)
{
if (lowcost[j] != 0 && lowcost[j] < min)
{
min = lowcost[j];
minid = j;
}
}
lowcost[minid] = 0;
sum += min;
for (int j = 2; j <= n; j++)
{
if (graph[minid][j] < lowcost[j])
{
lowcost[j] = graph[minid][j];
mst[j] = minid;
}
}
}
return sum;
}
void bfs(int target[][2],int i)
{
queue<Node> que;
Node node;
node.x = target[i][0];
node.y = target[i][1];
que.push(node);
dist[node.x][node.y] = 0;
int flag[MAX][MAX];
memset(flag, 0, sizeof(flag));
flag[node.x][node.y] = 1;
while (!que.empty())
{
Node now,next;
now = que.front();
que.pop();
for (int i = 0; i<4; i++)
{
int x = now.x + dir[i][0];
int y = now.y + dir[i][1];
if (x >= 0 && x<row && y >= 0 && y<col && map[x][y] != '#' && !flag[x][y])
{
next.x = x;
next.y = y;
que.push(next);
dist[x][y] = dist[now.x][now.y] + 1;
flag[x][y] = 1;
}
}
}
}
void constructGraph(int num,int target[][2])
{
for (int i = 0; i<num; i++)
{
bfs(target,i);
for (int j = 0; j<num; j++)
graph[i+1][j+1] = dist[target[j][0]][target[j][1]];
}
}
int main()
{
int cases;
//ifstream in("input.txt");
cin >> cases;
for (int i = 1; i <= cases; i++)
{
num = 1;
int target[MAX][2];
//construct the maze map
cin >> col >> row;
gets(map[0]);
for (int p = 0; p < row; p++)
{
gets(map[p]);
for (int q = 0; q < col; q++)
{
switch (map[p][q])
{
case 'A':
target[num][0] = p;
target[num++][1] = q;
break;
case 'S':
target[0][0] = p;
target[0][1] = q;
break;
default:
break;
}
}
}
constructGraph(num,target);
cout << prim(graph,num) << endl;
}
//system("pause");
return 0;
}