题意:坐飞机从 a 地到 b 地 ,在最多停留s次时 , 最小花费是多少?
在题目给出的地点 , 是按从远到近给出的 , 并且给出的航班中 , 不会有从远地点到近地点的航班。
因此从这可以看出 , 题目给的图是一个DAG图 , 那么我们就能用toposort来找最短路。
注意: 会有重边
解法:
构造一个数组 d[i][j] , 表示从开始点 s 到点 i , 在停留 j 次时的最小花费。
然后我们再求出这个图的toposort , 再求这个每一个点和其相邻点的距离。
代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <vector> #include <queue> #include <map> using namespace std; #define maxn 110 #define INF 0xfffffff int grap[maxn][maxn] ; long long d[maxn][maxn]; int n , m; int s1 , t1; int s; int index1[maxn]; //存储每个点的入度 int topo[maxn]; void init() { memset(grap , -1 , sizeof(grap)); memset(index1 , 0 , sizeof(index1)); s1 = 0 , t1 = n-1; s = n-2; } //可能会有重边 void add_edge(int x , int y , int z) { if(grap[x][y] == -1) { grap[x][y] = z; index1[y] += 1; } else if(grap[x][y] > z) grap[x][y] = z; } void toposort() { int i , u; int l = 0 , r = 0; for(i = 0; i < n; i++) if(index1[i] == 0) topo[r++] = i; while(l < r) { u = topo[l++]; for(i = 0; i < n; i++) if(grap[u][i] != -1 && index1[i] > 0) { index1[i]--; if(index1[i] == 0) topo[r++] = i; } } } void spfa() { int i , j; int u , v; for(i = 0; i < n; i++) for(j = 0; j <= s; j++) d[i][j] = INF; for(i = 0; i < n; i++) if(grap[s1][i] != -1) d[i][0] = grap[s1][i]; j = 1; while(j < n) { u = topo[j]; for(v = 0; v < s; v++) { if(d[u][v] == INF) continue; for(i = 0; i < n; i++) if(grap[u][i] != -1) { if(d[i][v+1] > d[u][v]+grap[u][i]) { d[i][v+1] = d[u][v]+grap[u][i]; } } } j++; } } int main() { //用map来区分每个点 //cout<<INF<<endl; int t , cas = 1; scanf("%d" , &t); while(t--) { scanf("%d" , &n); init(); map<string , int>ma; char city[30] , city2[30]; int i , x , y , z; for(i = 0; i < n; i++) { scanf("%s" , city); ma[city] = i; } map<string,int>::iterator it; scanf("%d" , &m); for(i = 0; i < m ; i++) { scanf("%s %s %d" , city , city2 , &z); it=ma.find(city); x = it->second; it=ma.find(city2); y = it->second; add_edge(x , y , z); } int q; toposort(); spfa(); for(i = 1; i <= s; i++) d[t1][i] = min(d[t1][i] , d[t1][i-1]); scanf("%d" , &q); printf("Scenario #%d\n" , cas++); for(i = 0; i < q; i++) { scanf("%d" , &x); x = x>s?s:x; if(d[t1][x] == INF) cout<<"No satisfactory flights"<<endl; else cout<<"Total cost of flight(s) is $"<<d[t1][x]<<endl; } if(t) cout<<endl; } return 0; } /* 2 4 Calgary Winnipeg Ottawa Fredericton 7 Calgary Ottawa 350 Calgary Winnipeg 125 Calgary Ottawa 300 Winnipeg Fredericton 325 Winnipeg Ottawa 100 Calgary Fredericton 875 Ottawa Fredericton 175 3 2 1 0 3 Calgary Montreal Fredericton 2 Calgary Montreal 300 Montreal Fredericton 325 1 0 */
uva 11280 状态压缩+最短路
时间: 2024-10-25 06:21:31