题意
T组样例,N个地点,每个地点有个繁忙度,地点间有M条街道,每条街道要收过路费(目的地繁忙度-起点繁忙度)^3 (3次方),有Q个查询,包含Q个目的地,求从起点1到每个目的地的最小花费。如果花费小于3或者无法到达目的地,则输出”?”
解题思路
由于目的地繁忙度不一定大于起点繁忙度,所以图中有负环(一开始没想到,直接用dijkstra一直WA),所以要用bellman_ford来求最短路,当某些地点位于负环内,就肯定最终花费小于3。
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int maxn = 1e3+5; const int maxm = 1e6+5; const int inf = 0x2f3f3f3f; int N,M; int A[maxn]; struct Edge { int from,to,cost; }; int dis[maxn]; bool vis[maxn]; Edge G[maxm];
void bellman_ford() { memset(dis,0x3f,sizeof(dis)); dis[1] = 0; for(int i=1;i<=N;i++){ for(int j=0;j<M;j++){ Edge e = G[j]; if(dis[e.from] + e.cost < dis[e.to]){ dis[e.to] = e.cost + dis[e.from]; if(i==N){ vis[e.from] = 1; vis[e.to] = 1; } } } } }
int main(int argc, char const *argv[]) { int T = 0; cin >> T; int Case = 1; while(T--){ cin >> N; for(int i=1;i<=N;i++){ cin >> A[i]; } cin >> M; int a,b; Edge e; memset(vis,0,sizeof(vis)); for(int i=0;i<M;i++){ cin >> a >> b; e.from = a; e.to = b; e.cost = pow(A[b]-A[a],3); G[i] = e; } int Q = 0; cin >> Q; cout << "Case " << Case++ << ":" << endl; bellman_ford(); for(int i=0;i<Q;i++){ int t = 0; cin >> t; if(dis[t] < 3 || dis[t]>=inf || vis[t]){ cout << "?" << endl; }else{ cout << dis[t] << endl; } } } return 0; }
|