题目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;
}

扩展:此题可以对应实际生活中根据地点地图定位(维度,经度),计算两个地点之间最短距离。