• ACM/ICPC 之 两道dijkstra练习题(ZOJ1053(POJ1122)-ZOJ1053)


      两道较为典型的单源最短路径问题,采用dijkstra解法

      本来是四道练习题,后来发现后面两道用dijkstra来解的话总觉得有点冗余了,因此暂且分成三篇博客(本篇以及后两篇)。


    ZOJ1053(POJ1122)-FDNY to the Rescue!

     1 //POJ1122-ZOJ1053
     2 //dijkstra-需要记录路径
     3 //给出n个路口的邻接矩阵,求给定多个火警到失火点的时间及任一路径
     4 //注意输入最后一行时,cin.getline需要两次,猜测需要接受邻接矩阵最后一行其他字符后再接受下一行(有误请指出)
     5 //POJ1122:Time:16Ms    Memory:208K    (单组数据)
     6 //ZOJ1053:Time:0Ms    Memory:276K    (多组数据,中间空一行)
     7 #include<iostream>
     8 #include<cstring>
     9 #include<cstdio>
    10 #include<algorithm>
    11 using namespace std;
    12 
    13 #define MAX 21
    14 #define INF 0x3f3f3f3f
    15 
    16 struct FD {    //FDNY
    17     int d;    //到失火点的距离
    18     int num;    //FD编号
    19     friend bool operator < (FD fd1, FD fd2) { return fd1.d < fd2.d; }
    20 }fd[MAX];
    21 
    22 int n;
    23 int road[MAX][MAX];    //有向图-road[i][j]:从i到j的距离
    24 int d[MAX];
    25 int fa[MAX];
    26 bool v[MAX];
    27 
    28 void dijkstra(int x)
    29 {
    30     memset(v, false, sizeof(v));
    31     v[x] = true;
    32     for (int i = 1; i <= n; i++)
    33     {
    34         d[i] = road[i][x];
    35         fa[i] = x;
    36     }
    37     for (int i = 1; i <= n; i++)
    38     {
    39         int mind = INF;
    40         int k;
    41         for (int j = 1; j <= n; j++)
    42             if (!v[j] && mind > d[j])
    43             {
    44                 mind = d[j];
    45                 k = j;
    46             }
    47         if (mind == INF) return;
    48         v[k] = true;
    49         for (int j = 1; j <= n; j++)
    50             if (!v[j] && d[j] > d[k] + road[j][k])
    51             {
    52                 d[j] = d[k] + road[j][k];
    53                 fa[j] = k;
    54             }
    55     }
    56 }
    57 
    58 int main()
    59 {
    60     int T;
    61     scanf("%d", &T);
    62     char str[2*MAX];
    63     cin.getline(str,2*MAX);
    64     while (T--)
    65     {
    66         scanf("%d", &n);
    67         for (int i = 1; i <= n; i++)
    68             for (int j = 1; j <= n; j++)
    69             {
    70                 scanf("%d", &road[i][j]);
    71                 if (road[i][j] == -1) road[i][j] = INF;
    72             }
    73         cin.getline(str, 2 * MAX);
    74         cin.getline(str, 2 * MAX);
    75 
    76         dijkstra(str[0] - '0');
    77         printf("Org	Dest	Time	Path
    ");
    78         int lenfd = 0;
    79         int len = strlen(str);
    80         for (int i = 2; i < len; i += 2)
    81         {
    82             fd[lenfd].num = str[i] - '0';
    83             fd[lenfd++].d = d[str[i] - '0'];
    84         }
    85 
    86         sort(fd, fd + lenfd);
    87         for (int i = 0; i < lenfd; i++)
    88         {
    89             printf("%d	%d	%d	%d", fd[i].num, str[0] - '0', fd[i].d, fd[i].num);
    90             int x = fd[i].num;
    91             while (fa[x] != x)
    92                 printf("	%d", x = fa[x]);
    93             printf("
    ");
    94         }
    95         if(T) printf("
    ");
    96     }
    97     return 0;
    98 }

    ZOJ1053-Transport Goods

     1 //dijkstra-松弛变形
     2 //题意中的cost请理解为Goods的代价(即消耗Goods的比例),可以比作路上会因各种情况损失货物的比例
     3 //博主用的是普通的最短路,不过WA了好几发,初始化-去重-松弛处理都有过问题(做了几个小时啊...)
     4 //可以转化为最长路,精度比博主会更好,不过针对此题并无必要
     5 //Time:0Ms    Memory:360K
     6 #include<iostream>
     7 #include<cstring>
     8 #include<cstdio>
     9 using namespace std;
    10 
    11 #define MAX 105
    12 #define INF 0x7f7f7f7f
    13 
    14 int n, m;
    15 double cost[MAX][MAX];
    16 double d[MAX], w[MAX];
    17 bool v[MAX];
    18 
    19 void dijkstra()
    20 {
    21     memset(v, false, sizeof(v));
    22     v[n] = true;
    23     for (int i = 1; i < n; i++)
    24         d[i] = cost[i][n];
    25     for (int i = 1; i <= n; i++)
    26     {
    27         double mind = 1;    //以1为上界
    28         int k;
    29         for (int j = 1; j < n; j++)
    30         {
    31             if (!v[j] && mind > d[j])
    32             {
    33                 mind = d[j];
    34                 k = j;
    35             }
    36         }
    37         if (mind > 1)    return;
    38         v[k] = true;
    39         for (int j = 1; j < n; j++)    //松弛
    40             if (!v[j] && cost[k][j] < 1 && d[j] > 1 - (1 - d[k]) * (1 - cost[k][j]))
    41                 d[j] = 1 - (1 - d[k]) * (1 - cost[k][j]);
    42     }
    43 }
    44 
    45 int main()
    46 {
    47     //freopen("in.txt", "r", stdin);
    48     //freopen("out.txt", "w", stdout);
    49     while (scanf("%d%d", &n, &m) != EOF)
    50     {
    51         memset(cost, INF, sizeof(cost));
    52         memset(w, 0, sizeof(w));
    53         for (int i = 1; i < n; i++)
    54             scanf("%lf", &w[i]);
    55         for (int j = 0; j < m; j++)
    56         {
    57             int x, y;
    58             double r;
    59             scanf("%d%d%lf", &x, &y, &r);
    60             if (cost[x][y] > r)        //去重
    61                 cost[y][x] = cost[x][y] = r;
    62         }
    63         dijkstra();
    64         for (int i = 1; i < n; i++)
    65             if (d[i] < 1)
    66                 w[n] += (1 - d[i]) * w[i];
    67         printf("%.2f
    ", w[n]);
    68     }
    69     return 0;
    70 }
    他坐在湖边,望向天空,她坐在对岸,盯着湖面
  • 相关阅读:
    python实现七段数码管显示
    词频统计实例
    分形几何中科赫雪花的绘制
    脚本实现自动化绘制
    Android查看数据库方法及工具(转)
    2011年度总结
    Bad NPObject as private data 解决方案
    LINQ学习之旅——LINQ TO SQL继承支持(转载)
    我记录开源系统1.6源码解析(一)
    2011年度总结
  • 原文地址:https://www.cnblogs.com/Inkblots/p/5452414.html
Copyright © 2020-2023  润新知