zoukankan      html  css  js  c++  java
  • 【HDU 2992 Hotel booking】spfa+floyd+map映射

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2992

    题目大意:有一家物流公司要送货炒年糕起点(1)送到终点(n),途中有n个城市其中只有h家客栈是免费休息的,途中有m条路通向不同的城市,开车的司机每天最多开10个小时的车程,问你起点送货到终点最少需要住几家客栈(规定只能住自家免费客栈)。 如果答案不存在输出-1。

    解题思路:

        司机从起点或者休息的客栈出发,落脚点必是下一家休息的客栈或者终点。所以对每家客栈(包括起点)spfa一次,找出客栈间最小车程小于十小时的,如果两件客栈间车程小于10小时则令他们的行走天数g[u][v]为1。  开始把终点也放入spfa了一次,wrong answer了一次。

       注意g[][]初始值赋为无穷大,客栈对应所在的城市用map映射一下(道理同节点离散化一样的),再对包括起点终点在内的所有客栈floyd一次,求出g[start][end]的值。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <map>
      4 #include <vector>
      5 #include <cstring>
      6 #include <algorithm>
      7 using namespace std;
      8 
      9 const int maxn=10005;
     10 const int INF=0x3fffffff;
     11 int que[maxn];
     12 int st[110];
     13 int g[110][110];
     14 int inque[maxn];
     15 int dis[maxn];
     16 int n, num;
     17 
     18 struct Node
     19 {
     20     int v, cost;
     21     Node(int v_,int cost_)
     22     {
     23         v=v_, cost=cost_;
     24     }
     25 };
     26 
     27 map<int,int>mp;
     28 vector<Node>vt[maxn];
     29 
     30 void spfa(int start)   ///可做模板
     31 {
     32     int h=0, t=0;
     33     for(int i=1; i<=n; i++)
     34     {
     35         dis[i]=INF;
     36         inque[i]=0;
     37     }
     38     dis[start]=0;
     39     inque[start]=1;
     40     que[t++]=start;
     41     while(h!=t)
     42     {
     43         int u=que[h++];
     44         inque[u]=0; ///出队列
     45         if(h==maxn) h=0;  ///!循环队列
     46         for(int i=0; i<vt[u].size(); i++)
     47         {
     48             int v=vt[u][i].v, cost=vt[u][i].cost;
     49             if(dis[v]>dis[u]+cost)
     50             {
     51                 dis[v]=dis[u]+cost;  ///松弛操作
     52                 if(!inque[v])   ///防止节点重复进队列
     53                 {
     54                     inque[v]=1;
     55                     que[t++]=v;
     56                     if(t==maxn) t=0;  ///循环队列
     57                 }
     58             }
     59         }
     60     }
     61     for(int i=1; i<=n; i++)
     62     {
     63         if(dis[i]<=600)
     64         {
     65             g[mp[start]][mp[i]]=1;
     66         }
     67     }
     68 }
     69 
     70 void floyd()
     71 {
     72     for(int k=0; k<=num+1; k++)
     73         for(int i=0; i<=num+1; i++)
     74            for(int j=0; j<=num+1; j++)
     75            {
     76                if(g[i][j]>g[i][k]+g[k][j])
     77                     g[i][j]=g[i][k]+g[k][j];
     78            }
     79 }
     80 
     81 int main()
     82 {
     83     int h, m, u, v, cost;
     84     while(cin >> n, n)
     85     {
     86         cin >> num;
     87         mp.clear();
     88         for(int i=0; i<=n; i++)
     89             vt[i].clear();
     90         for(int i=0; i<=num+2; i++)
     91             for(int j=0; j<=num+2; j++)
     92             {
     93                 g[i][j]=INF;
     94                 if(i==j) g[i][j]=0;
     95             }
     96         for(int i=1; i<=num; i++)
     97         {
     98             scanf("%d",st+i);
     99             mp[st[i]]=i;
    100         }
    101         st[0]=1;
    102         mp[1]=0;
    103         st[num+1]=n;
    104         mp[n]=num+1;
    105         cin >> m;
    106         for(int i=0; i<m; i++)
    107         {
    108             scanf("%d%d%d",&u,&v,&cost);
    109             vt[u].push_back(Node(v,cost));
    110             vt[v].push_back(Node(u,cost));
    111         }
    112         for(int i=0; i<=num; i++)
    113             spfa(st[i]);
    114         floyd();
    115         if(g[0][num+1]==INF)
    116             cout << -1 <<endl;
    117         else
    118             cout << g[0][num+1]-1 <<endl;
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    图片处理中的Dithering技术
    网络I/O模型
    并发编程(二)
    并发编程(一)
    socket编程(二)
    socket编程(一)
    异常处理
    软件开发规范
    面向对象进阶
    多态与封装
  • 原文地址:https://www.cnblogs.com/kane0526/p/2818747.html
Copyright © 2011-2022 走看看