题目1:
小美和小团在n行m列网格的图玩游戏,他们规定,有k个五元组(x,y,u,v,w),由x行y列网格向u行v列网格移动时花费为w,其它移动方式一律不合法,同时为了降低游戏难度,保证x≤u,y≤v.现在请求你从1行1列到n行列网格所需最小花费是多少?
输入描述:
第一行三个数n,m,k,表示行数、列数和五元组的个数。 接下来k行,每行5个数xi、yi、ui、vi、wi;含义如上文所述,保证给出各点有效且合法。 1≤n,m≤500,0≤wi≤100,0 ≤ k ≤ 50000
输出:
输出一个整数,表示答案,若无法从1行1列到n行m列,输出整数-1.
样例输入:
5 4 3 1 1 2 2 1 1 1 5 4 4 2 2 5 4 1
样例输出:
2
解题思路:
此题典型的求两点之间最短路径问题,使用dijkstra算法。
按照第二种思路,需要手从k*2个点中动统计出有多少点不重复点,可以使用set或者map集合进行去重统计处理。
实现:
#include<iostream> #include<map> #define N 5000 using namespace std; //map中如果key值 typedef struct MyDouble { int one; int two; //map中key值使用多个元素做key,使用的符合结构体, //在结构体里面需要重写"<"操作符,map中key只有一个元素时, // key在map中按照生序排列 bool operator<(const MyDouble& d)const { if(d.one < one && d.two < two){ return true; } else if (d.one < one && d.two > two) { return false; } else { return false; } } }MyDouble; typedef struct{ int city; }One; int edge[N][N],weight[N],disp[N]; bool visited[N] = {false}; const int inf = 99999; int main(){ int prev[N]; fill(edge[0],edge[0]+N*N,inf); fill(disp,disp+N,inf); int temp1,temp2,temp3; cin>>temp1>>temp2>>temp3; //转换 int n,m; n = 0; m = temp3; //使用map去重统计一共多少个点 map<MyDouble,int> mp; int x,y,u,v,w; int a,b,c; for(int i = 0;i < m;i++){ cin>>x>>y>>u>>v>>w; MyDouble city1 = {x,y}; if(mp.count(city1)<=0){ mp[city1] = n; a = n; n++; }else{ a = mp[city1]; } MyDouble city2 = {u,v}; if(mp.count(city2)<=0){ mp[city2] = n; b = n; n++; }else{ b = mp[city2]; } c = w; edge[a][b] = edge[b][a] = c; } for(int i = 0;i < N;i++){ prev[i] = i; edge[i][i] = 0; } //使用dijkstra算法求{1,1}到其它点最短距离 MyDouble city4 = {1,1}; int start_point = mp[city4]; disp[start_point] = 0; for(int i = 0;i < n;i++){ int u = -1,min = inf; for(int j = 0;j < n;j++){ if(visited[j] == false&& disp[j] <= min){ u = j; min = disp[j]; } } if(u == -1) break; visited[u] = true; for(int v = 0; v < n;v++){ if(visited[v] == false&& edge[u][v] != inf){ if(disp[u] + edge[u][v] < disp[v]){ disp[v] = disp[u] +edge[u][v]; prev[v] = u; } } } } //输出(1,1)到(5,4)最短距离 MyDouble city3 = {temp1,temp2}; int end_point = mp[city3]; if(disp[end_point] == inf){//没有路径 cout<<-1<<endl; }else{//有路径 cout<<disp[end_point]<<endl; } return 0; }
扩展:此题可以对应实际生活中根据地点地图定位(维度,经度),计算两个地点之间最短距离。