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

 

 

 

你可能感兴趣的:(floyd)