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