用spfa做的时候 标记每个点的被松弛的次数 即可。
View Code
1 #include <iostream> 2 #include <vector> 3 #include <cstring> 4 #include <queue> 5 #include <string> 6 #include <map> 7 #include <cstdio> 8 #define maxn 110 9 #define INF 1 << 30 10 using namespace std; 11 typedef pair<int,int> pii; 12 vector<int> v,next,w; 13 int first[maxn],e; 14 int inq[maxn][maxn],d[maxn][maxn]; 15 16 inline int min(int a,int b) 17 { 18 return a < b ? a : b; 19 } 20 21 void init() 22 { 23 v.clear(); 24 next.clear(); 25 w.clear(); 26 memset(first,-1,sizeof(first)); 27 e = 0; 28 } 29 30 void add_edge(int a,int b,int c) 31 { 32 v.push_back(b); 33 next.push_back(first[a]); 34 first[a] = e; 35 w.push_back(c); 36 e++; 37 } 38 39 void spfa(int start,int end,int n,int len) 40 { 41 if(len > maxn - 1) len = maxn - 1;//这里太淫荡了。。 42 queue <pii> q; 43 for(int i = 0;i <= len;i++) 44 for(int j = 0;j <= n;j++) 45 { 46 inq[i][j] = 0; 47 d[i][j] = INF; 48 } 49 50 d[0][start] = 0; 51 inq[0][start] = 1; 52 q.push(make_pair(0,start)); 53 54 while(!q.empty()) 55 { 56 int times = q.front().first; 57 int u = q.front().second; 58 //printf("current times = %d,current point = %d\n",times,u); 59 inq[times][u] = 0; 60 q.pop(); 61 62 for(int i = first[u];i != -1;i = next[i]) 63 { 64 if(times + 1 <= len && d[times + 1][v[i]] > d[times][u] + w[i]) 65 { 66 //printf("succeed:times = %d,point = %d,dist = %d\n",times,v[i],d[times][u] + w[i]); 67 d[times + 1][v[i]] = d[times][u] + w[i]; 68 if(!inq[times + 1][v[i]]) 69 { 70 inq[times + 1][v[i]] = 1; 71 q.push(make_pair(times + 1,v[i])); 72 } 73 } 74 } 75 } 76 77 int ans = INF; 78 for(int t = 0;t <= len;t++) 79 ans = ans < d[t][end] ? ans : d[t][end]; 80 81 if(ans == INF) printf("No satisfactory flights\n"); 82 else printf("Total cost of flight(s) is $%d\n",ans); 83 } 84 85 int main() 86 { 87 int T; 88 scanf("%d",&T); 89 for(int kase = 1;kase <= T;kase++) 90 { 91 map<string,int> m; 92 int start,end; 93 int n,M; 94 scanf("%d",&n); 95 for(int i = 0;i < n;i++) 96 { 97 string str; 98 cin>>str; 99 m[str] = i; 100 if(str == "Calgary") start = i; 101 else if(str == "Fredericton") end = i; 102 } 103 //printf("start = %d,end = %d\n",start,end); 104 init(); 105 scanf("%d",&M); 106 for(int i = 0;i < M;i++) 107 { 108 int cost; 109 string str1,str2; 110 cin>>str1>>str2>>cost; 111 add_edge(m[str1],m[str2],cost); 112 } 113 114 if(kase > 1) printf("\n"); 115 printf("Scenario #%d\n",kase); 116 int q,len; 117 scanf("%d",&q); 118 while(q--) 119 { 120 scanf("%d",&len); 121 spfa(start,end,n,len + 1); 122 } 123 124 } 125 return 0; 126 }