zoukankan      html  css  js  c++  java
  • [原]最短路专题【基础篇】(updating...)

    hud1548 a strange lift  最短路/bfs  题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1548

    题意:一个奇怪的电梯,每层楼的按键 只能上达 i + k[i] 层,下至 i- k[i] 层。不能到达超过n楼, 也不能小于 1楼。问最少按键数。以单个0结束输入。

    思路:bfs, 从起点出发,每个楼层只会访问一次,在不出界的情况下访问能够到达的楼层。

    总结:布吉岛神马原因,只有用G++交才过,导致我纠结了好多天,【摔发火】!

    AC代码:

     1 //AC
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<queue>
     6 #include<limits.h>
     7 using namespace std;
     8 #define maxn 2000
     9 #define INF INT_MAX
    10 int n, a, b;
    11 int arr[maxn];
    12 bool inq[maxn];
    13 int dis[maxn];
    14 
    15 void bfs(int st){
    16    queue<int> q;
    17    q.push(st);
    18    int x;
    19    dis[st] = 0;
    20    if(a < 1||a > n||b < 1||b > n) return;
    21    while(!q.empty()){
    22      x = q.front();
    23      q.pop();
    24      if(x < 1||x > n||x == b) break;
    25      if(x+arr[x] >= 1&&x+arr[x] <= n&&!inq[x+arr[x]]) { q.push(x+arr[x]); inq[x+arr[x]] = 1; dis[x+arr[x]] = dis[x] + 1; }
    26      if(x-arr[x] >= 1&&x-arr[x] <= n&&!inq[x-arr[x]]) { q.push(x-arr[x]); inq[x-arr[x]] = 1; dis[x-arr[x]] = dis[x] + 1; }
    27      //if(x+arr[x]>n&&x-arr[x]<1) break;
    28    }
    29 }
    30 int main(){
    31    while(~scanf("%d",&n) ,n){
    32     scanf("%d%d", &a, &b);
    33       for(int i = 1; i <= n; i++)
    34         scanf("%d",&arr[i]);
    35       memset(inq, 0, sizeof(inq));
    36       for(int i = 0; i <= maxn; i++){
    37         dis[i] = INF;
    38       }
    39       bfs(a);
    40       printf("%d
    ", (dis[b] == INF)?-1:dis[b]);
    41    }
    42 }
    View Code

    hdu2544    最短路题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544

    题意:正如题目所说,是最短路,可以说是单源最短路入门题。

    思路:可以用dijkstra做,这里我用spfa,不知道写的规不规范,总之思路和bellman-ford很像的,相当于Bellman-Ford的队列优化,也相当于做一趟bfs,具体是从当前节点出发,访问所有节点,如果能够到达,且被访问节点到起点的值比当前节点到起点的值加上当前节点到该节点大,则更新被访问的节点到起点的值,如果节点不在队列中,则入队,复杂度最坏是O(mn)。

    总结:写完交wa了N+1次,最后才发现是INF的值没设好,Σ(っ °Д °;)っ设小了可能比更新后的距离小了,设大了,比如INT_MAX又溢出了。。。所以后来设成 节点数X单条路径最大距离  再大一点点就过了~~T^T

    AC代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<limits.h>
     5 #include<queue>
     6 using namespace std;
     7 #define maxn 109
     8 #define INF 1000011
     9 int n, m, w[maxn][maxn];
    10 void spfa()
    11 {
    12   int d[maxn], k;
    13   bool inq[maxn];
    14   for(int i = 0; i <= n; i++) {d[i] = INF; inq[i] = false;}
    15   d[1] = 0;
    16   //inq[1] = true;
    17   queue<int> q;
    18   q.push(1);
    19   while(!q.empty()){
    20      k = q.front(); q.pop();
    21      inq[k] = false;
    22      for(int j = 2; j <= n; j++){
    23        int t = d[k] + w[k][j];
    24        if(d[j] > t){
    25           d[j] = t;
    26           if(!inq[j]){
    27              q.push(j);
    28              inq[j] = true;
    29           }
    30        }
    31      }
    32   }
    33   printf("%d
    ",d[n]);
    34 }
    35 
    36 int main()
    37 {
    38   while(scanf("%d%d", &n, &m)&&n&&m){
    39     for(int i = 0; i <= n; i++)
    40      for(int j = 0; j <= n; j++)
    41         w[i][j] = (i == j)?0:INF;
    42 
    43     for(int i = 0; i < m; i++){
    44        int a, b, c;
    45        scanf("%d%d%d", &a, &b, &c);
    46        w[a][b] = w[b][a] =c;
    47     }
    48     spfa();
    49   }
    50   return 0;
    51 }
    View Code

    hdu 3790 最短路径问题 基础最短路

    思路:基础最短路,先考虑路径再考虑费用

    总结:WA原因, 输入时没考虑 a, b 之间存在多条路径

    AC代码:

    spfa版

     1 //spfa版
     2 
     3 #include<iostream>
     4 #include<cstdio>
     5 #include<cstring>
     6 #include<limits.h>
     7 #include<queue>
     8 using namespace std;
     9 #define maxn 2000
    10 #define INF INT_MAX-100001
    11 int n, m, a, b, d, p, s, t;
    12 int w[maxn][maxn], cost[maxn][maxn];
    13 struct node{
    14   int dis, cos;
    15 };
    16 
    17 void test(node* x){
    18   for(int i = 0; i <= n; i++)
    19   {
    20      cout<<x[i].dis<<" "<<x[i].cos<<endl;
    21   }
    22 }
    23 
    24 void spfa(int s, int t)
    25 {
    26   node d[maxn]; bool inq[maxn]; memset(inq, 0, sizeof(inq));
    27   int k;
    28   for(int i = 0; i < maxn; i++)
    29    d[i].dis = d[i].cos = INF;
    30 
    31   d[s].dis = d[s].cos = 0; inq[s] = true;
    32   queue<int> q;
    33   q.push(s);
    34   while(!q.empty()){
    35      k = q.front(); q.pop();
    36      inq[k] = false;
    37      for(int i = 0; i <= n; i++){
    38        if(i != k){
    39          int t1 = d[k].dis + w[k][i];  int t2 = d[k].cos + cost[k][i];
    40          if(t1 < d[i].dis){
    41            d[i].dis = t1;
    42            d[i].cos = t2;
    43            if(!inq[i]) { q.push(i); inq[i] = true; }
    44          }
    45          if(t1 == d[i].dis&&t1 != INF){
    46            if(t2 < d[i].cos) {
    47             d[i].cos = t2;
    48            }
    49            if(!inq[i]){ q.push(i); inq[i] = true; }
    50          }
    51        }
    52      }
    53   }
    54   //test(d);
    55   printf("%d %d
    ", d[t].dis, d[t].cos);
    56 
    57 }
    58 void init()
    59 {
    60   for(int i = 0; i <= n; i++)
    61     for(int j = 0; j <= n; j++){
    62        w[i][j] = cost[i][j] = (i == j)?0:INF;
    63     }
    64 }
    65 int main()
    66 {
    67   while(scanf("%d%d", &n, &m),n,m){
    68     init();
    69     for(int i = 0; i < m; i++){
    70       scanf("%d%d%d%d", &a, &b, &d, &p);
    71       if(d < w[a][b]){
    72       w[a][b] = w[b][a] = d;
    73       cost[a][b] = cost[b][a] = p;
    74       }
    75     }
    76     scanf("%d%d", &s, &t);
    77 
    78     spfa(s, t);
    79   }
    80   return 0;
    81 }
    View Code

    dijkstra版

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<stack>
     7 #include<string>
     8 #include<cmath>
     9 #define maxn 1024
    10 #define INF 0x3fffffff
    11 using namespace std;
    12 int n, m;
    13 int d[maxn];
    14 struct node{
    15    int dis, cos;
    16 };
    17 node arr[maxn][maxn];
    18 
    19 void test(int* c, int*d){
    20   for(int i = 1; i <= n; i++){
    21    cout<<i<<" dis "<< c[i]<<" cost "<<d[i]<<endl;
    22   }
    23 }
    24 
    25 void dijkstra(int s, int t)
    26 {
    27   int d[maxn], cost[maxn];
    28   bool vis[maxn];
    29   memset(vis, false, sizeof(vis));
    30   for(int i = 0; i < maxn; i++)
    31    d[i] = cost[i] = INF;
    32   d[s] = cost[s] = 0;
    33 
    34   for(int i = 1; i <= n; i++){
    35     int k, mm = INF;
    36 
    37     for(int j = 1; j <= n; j++) if(!vis[j] && d[j] < mm) { mm = d[j]; k = j; }
    38     vis[k] = true;
    39 
    40     for(int j = 1; j <= n; j++){
    41       if(d[j] > d[k] + arr[k][j].dis){
    42         d[j] = d[k] + arr[k][j].dis;
    43         cost[j] = cost[k] + arr[k][j].cos;
    44       }
    45       else if(d[j] < INF && d[j] == d[k] + arr[k][j].dis && cost[j] > cost[k] + arr[k][j].cos){
    46         cost[j] = cost[k] + arr[k][j].cos;
    47       }
    48     }
    49   }
    50 //test(d, cost);
    51   printf("%d %d
    ", d[t], cost[t]);
    52 }
    53 
    54 int main(){
    55   while(scanf("%d%d", &n, &m) == 2 &&(n||m)){
    56     for(int i = 0; i <= n; i++){
    57       for(int j = 0; j <= n; j++)
    58       {
    59         arr[i][j].dis = arr[i][j].cos = (i == j)?0:INF;
    60       }
    61     }
    62     for(int i = 0; i < m; i++){
    63       int a, b, c, d;
    64       scanf("%d%d%d%d", &a, &b, &c, &d);
    65       if(c < arr[a][b].dis){
    66         arr[a][b].dis = arr[b][a].dis = c;
    67         arr[a][b].cos = arr[b][a].cos = d;
    68       }
    69     }
    70     int s, t;
    71     scanf("%d%d", &s, &t);
    72     dijkstra(s, t);
    73   }
    74   return 0;
    75 }
    View Code
    
    

    hdu 2066 一个人的旅行  【多源多汇,基础最短路】

    思路:邻接表存图。 多源多汇,所以考虑建立【超级原点】,通常为0点,该点到所有起点的距离都为0,然后就是裸的最短路了。

    总结:不知道为什么在自己电脑上init()之后s就被莫名其妙地改变成和t一个值了。。。。但是无改动用C++交上去过了,= =||,如果谁知道为神马请告诉我一声,涩涩~~~

    AC代码如下:

     1 //AC
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<queue>
     5 #include<vector>
     6 #include<limits.h>
     7 #include<cstring>
     8 using namespace std;
     9 #define maxn 1010
    10 #define INF INT_MAX-1000
    11 struct node{
    12    int v, wei;
    13 };
    14 vector<node> gra[maxn];
    15 int t, s, d;  int dis[maxn];
    16 
    17 void init()
    18 {
    19     int i;
    20     for(i = 0; i <= maxn; i++)
    21         gra[i].clear();
    22 }
    23 
    24 void input()
    25 {
    26    for(int i = 0; i < t; i++){
    27        node re;
    28        int u, v, w;
    29        scanf("%d%d%d", &u, &v, &w);
    30        re.v = v; re.wei = w;
    31        gra[u].push_back(re);
    32        re.v = u;
    33        gra[v].push_back(re);
    34    }
    35    for(int i = 0; i < s; i++){
    36        node re; re.wei = 0;
    37        scanf("%d", &re.v);
    38        gra[0].push_back(re);
    39        int t = re.v; re.v = 0;
    40        gra[t].push_back(re);
    41    }
    42 }
    43 
    44 void output()
    45 {
    46    int ans = INF;
    47    for(int i = 0; i < d; i++){
    48      int fina;
    49      scanf("%d", &fina);
    50      if(dis[fina] < ans) ans = dis[fina];
    51    }
    52    printf("%d
    ", ans);
    53 }
    54 
    55 
    56 void spfa()
    57 {
    58    bool inq[maxn];  memset(inq, 0, sizeof(inq));
    59    for(int i = 0; i < maxn; i++)
    60      dis[i] = INF;
    61 
    62    queue<int> q;
    63    q.push(0);
    64    inq[0] = true; dis[0] = 0;
    65    while(!q.empty()){
    66       int u = q.front(); q.pop();
    67       inq[u] = false;
    68       for(int i = 0; i < gra[u].size(); i++){
    69         int t = dis[u] + gra[u][i].wei;
    70         int v = gra[u][i].v;
    71         if(dis[v] > t){
    72           dis[v] = t;
    73           if(!inq[v]){
    74             q.push(v);
    75             inq[v] = true;
    76           }
    77         }
    78       }
    79    }
    80 }
    81 
    82 int main()
    83 {
    84    while(scanf("%d%d%d", &t, &s, &d) != EOF){
    85      init();
    86      input();
    87      spfa();
    88      output();
    89    }
    90    return 0;
    91 }
    View Code

    同类型基础题如下:

    1869 六度分离 Floyd最短路(water)

    作者:u011652573 发表于2014-4-22 8:12:45 原文链接
    阅读:82 评论:0 查看评论
  • 相关阅读:
    批处理(bat)的一些记录
    在 Docker 中已运行的 container 如何修改 run 时的 env
    Linux 的一些命令记录
    Javascript aop(面向切面编程)之around(环绕)
    dojo Provider(script、xhr、iframe)源码解析
    dojo/request模块整体架构解析
    require、module、exports dojo中的三个特殊模块标识
    CSS垂直居中总结
    Javascript图片裁切
    CSS Font知识整理总结
  • 原文地址:https://www.cnblogs.com/ZiningTang/p/3834748.html
Copyright © 2011-2022 走看看