zoukankan      html  css  js  c++  java
  • 九度oj题目1008:最短路径问题

    题目描述:                       

    给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
    输入:                       
    输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。 (1<n<=1000, 0<m<100000, s != t)
    输出:                       
    输出 一行有两个数, 最短距离及其花费。
    样例输入:                       
    3 2
    1 2 5 6
    2 3 4 5
    1 3
    0 0
    样例输出:                       
    9 11
    通过这道题复习了一下迪杰特斯拉算法,算法的精髓在于每回找一个距离集合最近的点加到集合中,直到不能加入更多的点为止
    代码如下:
     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <string>
     5 #include <algorithm>
     6 #define MAX 999999999
     7 #define N 1005
     8 #define M 100005
     9 
    10 struct Way {
    11     int distance;
    12     int cost;
    13 };
    14 
    15 Way map[N][N];//邻接矩阵
    16 Way dis[N];//起点到各个点的距离表
    17 int flag[N];//判别某点是否在已包括点的集合中
    18 
    19 void dijkstra(int start, int end,int n) {
    20     memset(flag,0,sizeof(int)*N);
    21     //初始化距离
    22     for(int i = 1; i <= n; i++) {
    23         dis[i] = map[start][i];
    24     }
    25     dis[start].distance = 0;//该点到自己的距离为0
    26     dis[start].cost = 0;//到自己的花费为0
    27     flag[start] = 1;//把自己包括到可以到达的点中
    28 
    29     for(int i = 1; i < n; i++) {
    30         //总共需要加入n-1个点,所以循环n-1次
    31         int index = 0;
    32         int min = MAX;
    33         for(int j = 1; j <= n; j++) {
    34             if(flag[j] == 0 && dis[j].distance < min) {
    35                 index = j;
    36                 min = dis[j].distance;
    37             }
    38         }
    39         //find the min index
    40         flag[index] = 1;
    41 
    42         for(int j = 1; j <= n; j++) {
    43             if(flag[j] == 0 && (dis[index].distance + map[index][j].distance < dis[j].distance)) {
    44                 dis[j].distance = dis[index].distance + map[index][j].distance;
    45                 dis[j].cost = dis[index].cost + map[index][j].cost;
    46             }
    47             else if(flag[j] == 0 && (dis[index].distance + map[index][j].distance == dis[j].distance)){
    48                 if(dis[j].cost > dis[index].cost + map[index][j].cost) {
    49                     dis[j].cost = dis[index].cost + map[index][j].cost;
    50                 }
    51             }
    52         }
    53     }
    54 
    55     
    56 }
    57 
    58 int main(int argc, char const *argv[])
    59 {
    60     int n,m;
    61     int source, des;
    62     scanf("%d %d",&n,&m);
    63     while(n != 0 && m != 0) {
    64         for(int i = 1; i <= n; i++) {
    65             for(int j = 1; j <= n; j++) {
    66                 map[i][j].distance = MAX;
    67                 map[i][j].cost = MAX;
    68             }
    69         }
    70         int pointA,pointB,disc,cost;
    71         for(int i = 0; i < m; i++) {
    72             scanf("%d %d %d %d",&pointA,&pointB,&disc,&cost);
    73             map[pointA][pointB].distance = disc; 
    74             map[pointB][pointA].distance = disc;
    75             map[pointA][pointB].cost = cost;
    76             map[pointB][pointA].cost = cost;
    77         }
    78         scanf("%d %d",&source,&des);
    79 
    80         dijkstra(source,des,n);
    81         printf("%d %d
    ",dis[des].distance,dis[des].cost);
    82         scanf("%d %d",&n,&m);
    83     }
    84     return 0;
    85 }

     最近尝试了一下用优先队列来解决问题,感觉写得很别扭,不过还是写出来了,速度提高不少,代码如下

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <vector>
     4 #include <queue>
     5 
     6 #define MAX_V 1002
     7 #define inf 999999999
     8 using namespace std;
     9 
    10 struct Edge
    11 {
    12 public:
    13     int to;
    14     int dis;
    15     int cost;
    16     Edge(int to, int dis,int cost) {
    17         this->to = to;
    18         this->dis = dis;
    19         this->cost = cost;
    20     }
    21 };
    22 
    23 struct cmp{
    24     bool operator()(const Edge &a,const Edge &b){
    25         if(a.dis == b.dis) {
    26             return a.cost - b.cost;
    27         }
    28         else {
    29             return a.dis - b.dis;
    30         }
    31     }
    32 };
    33 typedef pair<int , int> P;//first dis, sencond cost
    34 P dist[MAX_V];
    35 vector<Edge> G[MAX_V];
    36 priority_queue<Edge, vector<Edge>, cmp> que;
    37 
    38 int main(int argc, char const *argv[])
    39 {
    40     int n,m;
    41     int source, des;
    42     freopen("input.txt","r",stdin);
    43     while(scanf("%d %d",&n,&m) != EOF && (n != 0 && m != 0)) {
    44         for(int i = 0; i <= n; i++) {
    45             G[i].clear();
    46         }
    47         for(int i = 0; i < m; i++) {
    48             int a, b, disc, cost;
    49             scanf("%d %d %d %d",&a,&b,&disc,&cost);
    50             G[a].push_back(Edge(b,disc,cost));
    51             G[b].push_back(Edge(a,disc,cost));
    52         }
    53         scanf("%d %d",&source,&des);
    54         fill(dist,dist+n+1,P(inf,inf));
    55         dist[source] = P(0,0);
    56         que.push(Edge(source,0,0));
    57 
    58         while(!que.empty()) {
    59             Edge t = que.top(); que.pop();
    60             int v = t.to, d = t.dis, c = t.cost;
    61             if(dist[v].first < d) {
    62                 continue;
    63             }
    64             for(int i = 0; i < G[v].size(); i++) {
    65                 Edge &e = G[v][i];
    66                 int d2 = d + e.dis;
    67                 int c2 = c + e.cost;
    68 
    69                 if(dist[e.to].first > d2 || (dist[e.to].first == d2 && dist[e.to].second > c2)) {
    70                     dist[e.to] = P(d2,c2);
    71                     que.push(Edge(e.to,d2,c2));
    72                 }
    73             }
    74         }
    75         printf("%d %d
    ",dist[des].first,dist[des].second);
    76 
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    WebClient 非阻塞客户端 RestTemplate 阻塞式客户端
    微服务网关---调用其他微服务
    复习下comparable和comparator以及比较
    关于InitializingBean的用法、应用
    Scheduled(cron = "")
    windows查看进程方法(老是忘只能写了)
    vue 控件component
    vue 过滤器的使用实例
    vue基础
    日志脱敏工具
  • 原文地址:https://www.cnblogs.com/jasonJie/p/5661595.html
Copyright © 2011-2022 走看看