• poj1847 Tram(Dijkstra || Floyd || SPFA)


    题目链接

    http://poj.org/problem?id=1847

    题意

    有n个车站,编号1~n,每个车站有k个出口,车站的出口默认是k个出口中的第一个,如果不想从默认出口出站,则需要手动选择出站口。现在从车站a出发,求最少需要手动选择几次出站口才能到车站b。

    思路

    这题的图中没有显式给出结点之间的距离,但可以根据题意给路径添加距离,比如测试数据中的“2 2 3”表示从第1个车站默认开往第2个车站,想要开到第3个车站则需手动选择,所以我们可以令结点1到结点2的边权值为0(默认车站),结点1到结点3边权值为1(需手动选择的车站),这样就可以使用Dijkstra算法、Floyd算法或者SPFA算法求解a,b之间的最短路,a,b之间最短路的值即是需手动选择车站的次数。

    代码

    Dijkstra算法和Floyd算法:

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 using namespace std;
     6 
     7 const int INF = 0x3f3f3f;
     8 const int N = 100 + 10;
     9 int map[N][N];
    10 int dist[N];
    11 int visit[N];
    12 int n, a, b;
    13 
    14 void dijkstra()    //Dijkstra算法
    15 {
    16     memset(visit, 0, sizeof(visit));
    17     for (int i = 1; i <= n; i++)
    18         dist[i] = map[a][i];
    19     dist[a] = 0;
    20     visit[a] = 1;
    21     int min_dist, now = a;
    22     for (int i = 1; i <= n; i++)
    23     {
    24         min_dist = INF;
    25         for (int j = 1; j <= n; j++)
    26         {
    27             if (!visit[j] && dist[j] < min_dist)
    28             {
    29                 min_dist = dist[j];
    30                 now = j;
    31             }
    32         }
    33         visit[now] = 1;
    34         for (int j = 1; j <= n; j++)
    35             dist[j] = min(dist[j], dist[now] + map[now][j]);
    36     }
    37     if (dist[b] >= INF)    //注意是dist[b]>=INF,不是dist[b]==INF
    38         puts("-1");
    39     else printf("%d
    ", dist[b]);
    40 }
    41 
    42 void floyd()    //Floyd算法
    43 {
    44     for (int k = 1; k <= n; k++)
    45         for (int i = 1; i <= n; i++)
    46             for (int j = 1; j <= n; j++)
    47                 map[i][j] = min(map[i][j], map[i][k] + map[k][j]);
    48     if (map[a][b] >= INF)
    49         puts("-1");
    50     else printf("%d
    ", map[a][b]);
    51 }
    52 
    53 int main()
    54 {
    55     //freopen("poj1847.txt", "r", stdin);
    56     while (scanf("%d%d%d", &n, &a, &b) == 3)
    57     {
    58         memset(map, INF, sizeof(map));
    59         int k, t;
    60         for (int i = 1; i <= n; i++)
    61         {
    62             scanf("%d", &k);
    63             for (int j = 1; j <= k; j++)
    64             {
    65                 scanf("%d", &t);
    66                 if (j == 1)
    67                     map[i][t] = 0;
    68                 else map[i][t] = 1;
    69             }
    70         }
    71         dijkstra();
    72         //floyd();
    73     }
    74     return 0;
    75 }

    SPFA算法:

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <vector>
     6 #include <queue>
     7 using namespace std;
     8 
     9 struct Edge
    10 {
    11     int s, e, dist;
    12 
    13     Edge() {}
    14     Edge(int s, int e, int d) :s(s), e(e), dist(d) {}
    15 };
    16 
    17 const int INF = 0x3f3f3f;
    18 const int N = 100 + 10;
    19 vector<Edge> v[N];
    20 int dist[N];
    21 int visit[N];
    22 int n, a, b;
    23 
    24 void spfa(int s)
    25 {
    26     queue<int> q;
    27     memset(dist, INF, sizeof(dist));
    28     memset(visit, 0, sizeof(visit));
    29     q.push(s);
    30     visit[s] = 1;
    31     dist[s] = 0;
    32 
    33     while (!q.empty())
    34     {
    35         int s = q.front();
    36         q.pop();
    37         visit[s] = 0;
    38         for (int i = 0; i < v[s].size(); i++)
    39         {
    40             int e = v[s][i].e;
    41             if (dist[e] > dist[s] + v[s][i].dist)
    42             {
    43                 dist[e] = dist[s] + v[s][i].dist;
    44                 if (!visit[e])
    45                 {
    46                     visit[e] = 1;
    47                     q.push(e);
    48                 }
    49             }
    50         }
    51     }
    52     if (dist[b] >= INF)
    53         puts("-1");
    54     else printf("%d
    ", dist[b]);
    55 }
    56 
    57 int main()
    58 {
    59     //freopen("poj1847.txt", "r", stdin);
    60     while (scanf("%d%d%d", &n, &a, &b) == 3)
    61     {
    62         for (int i = 1; i <= n; i++)
    63             v[i].clear();
    64 
    65         int k, t;
    66         for (int i = 1; i <= n; i++)
    67         {
    68             scanf("%d", &k);
    69             for (int j = 1; j <= k; j++)
    70             {
    71                 scanf("%d", &t);
    72                 if (j == 1)
    73                     v[i].push_back(Edge(i, t, 0));
    74                 else v[i].push_back(Edge(i, t, 1));
    75             }
    76         }
    77         spfa(a);    //求结点a到其余各点的最短路径
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    VUE动态组件component以及<keep-alive>
    git flow工作流
    vue组件通讯
    webpack加载器和自动打包工具
    webpack的插件使用,以及引入vue文件的注意事项
    webpack起步以及手动配置config文件
    git 基本操作
    C++中静态成员变量的可以在类内初始化吗?
    python 环境变量设置PYTHONPATH
    vector中resize和reserve的区别
  • 原文地址:https://www.cnblogs.com/sench/p/7978856.html
Copyright © 2020-2023  润新知