【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 }

 

 

 

posted @ 2012-12-14 22:17  Mr. Ant  阅读(439)  评论(0编辑  收藏  举报