解题策略:典型的Djstra单源路径最短问题.问题的关键是将矩阵化为图的形式.
#include <iostream>
#include <vector>
#include <string>
#include <memory.h>
#include <cstring>
using namespace std;
struct edge
{
int v;//点
int cost;//权值
edge(int a,int b)
{
this->v = a;
this->cost = b;
}
};
const int MAXN = 1000005;
const int N = 10005;
bool used[N];
int minlength[N];
vector<edge> map[N];
int matrix[105][105];
int num[105][105];
int col,row;//举证的行和列
int number;//转化的图中点的个数
int djstra(int start,int end)
{
memset(used,false,sizeof(used));
for(int i = 1;i <= number;i++)
minlength[i] = (i == start ? 0 : MAXN);
used[start] = true;
for(int i = 1;i <= number;i++)
{
int temp_min = MAXN,a = start;
for(int j = 1;j <= number;j++)
{
if(!used[j] && minlength[j] < temp_min)
{
temp_min = minlength[j];
a = j;
}
}
used[a] = true;
for(int i = 0;i < map[a].size();i++)
{
int tempv = map[a][i].v;
int cost = map[a][i].cost;
if(!used[tempv] && minlength[tempv] > minlength[a] + cost)
minlength[tempv] = minlength[a] + cost;
}
}
return minlength[end];
}
int main()
{
int n,m;
cin >> n;
while(n--)
{
int start_x,start_y,end_x,end_y;
number = 0;
cin >> col >> row;
for(int i = 1;i <= col;i++)
for(int j = 1;j <= row;j++)
{
cin >> matrix[i][j];
num[i][j] = number++;
}
//将矩阵转化成图
for(int x = 1;x <= col;x++)
for(int y = 1;y <= row;y++)//对点(x,y)的上下左右探索,若点存在,则当做从点(x,y)到此点有一条边,且权值为此点的matrix值
{
if(num[x][y - 1])//上
{
map[num[x][y]].push_back(edge(num[x][y - 1],matrix[x][y - 1]));
}
if(num[x + 1][y])//右
{
map[num[x][y]].push_back(edge(num[x + 1][y],matrix[x + 1][y]));
}
if(num[x][y + 1])//下
{
map[num[x][y]].push_back(edge(num[x][y + 1],matrix[x][y + 1]));
}
if(num[x - 1][y])//左
{
map[num[x][y]].push_back(edge(num[x - 1][y],matrix[x - 1][y]));
}
}
cin >> start_x >> start_y >> end_x >> end_y;
cout << djstra(num[start_x][start_y],num[end_x][end_y]) + matrix[start_x][start_y] << endl;
for(int i = 0; i < number + 2;i++)
{
map[i].clear();
}
}
return 0;
}