UVa11280 Flying to Fredericton

难得的一A

与SPFA判负圈的思想类似. 记录一下入队次数就ok.

我想到的一些优化:

可以找到Q中最大的一个当做入队次数的上界.

因为是多次入队,选择SPFA而非dijkstra (dijkstra会多一个logn)

因为我懒, 以上优化并没有实现,因为在这个数据规模下随便怎么写都行啦

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <iostream>
  5 #include <vector>
  6 #include <queue>
  7 #include <map>
  8 using namespace std;
  9 const int MAXN = 1e2 + 20;
 10 const int INF = 0x3f3f3f3f;
 11 
 12 map<string, int> num; int numcnt = 0;
 13 inline int getnum(string &s)
 14 {
 15     if(num.find(s) == num.end()) 
 16         return (num[s] = ++numcnt, numcnt);
 17     else return num[s]; 
 18 }
 19 struct edge
 20 {
 21     int to, cost;
 22     edge(int v = 0, int c = 0) : 
 23     to(v), cost(c) {}
 24 };vector<edge> g[MAXN];
 25 struct state
 26 {
 27     int pos, k, cost;
 28     state(int p = 0, int k = 0, int c = 0) :
 29     pos(p), k(k), cost(c) {}
 30     bool operator >(const state &lhs) const{
 31         return cost > lhs.cost;
 32     }
 33 };
 34 int N, M, Q, S, T;
 35 
 36 int f[MAXN][MAXN];
 37 bool vis[MAXN][MAXN];
 38 
 39 inline bool tension(const int &st, int &lg)
 40 {
 41     return st < lg ? (lg = st, true) : false;
 42 }
 43 
 44 priority_queue<state, vector<state>, greater<state> > q;
 45 void bfs()
 46 {
 47     f[S][0] = 0, q.push(state(S, 0, 0));
 48     while(!q.empty())
 49     {
 50         state u = q.top(); q.pop();
 51         if(u.k > N || vis[u.pos][u.k]) continue;
 52         vis[u.pos][u.k] = true;
 53         for(int i = 0; i < (int) g[u.pos].size(); i++)
 54         {
 55             edge &e = g[u.pos][i];
 56             if(tension(f[u.pos][u.k] + e.cost, f[e.to][u.k + 1]))
 57                 q.push(state(e.to, u.k + 1, f[e.to][u.k + 1]));
 58         }
 59     }
 60 }
 61 
 62 void init()
 63 {
 64     memset(vis, false, sizeof(vis));
 65     memset(f, 0x3f, sizeof(f));
 66     num.clear(); numcnt = 0;
 67     for(int i = 1; i <= N; i++) g[i].clear();
 68 }
 69 
 70 int main()
 71 {
 72     //freopen("11280.out", "w", stdout);
 73     int b, t = 0; cin>>b;
 74     while(b--)
 75     {
 76         if(t) puts("");
 77         t++; cin>>N;
 78         string s; init();
 79         for(int i = 1; i <= N; i++) {cin>>s; getnum(s);}
 80         cin>>M;
 81         for(int i = 1, u, v, c; i <= M; i++)
 82         {
 83             cin>>s; u = getnum(s);
 84             cin>>s; v = getnum(s);
 85             cin>>c; g[u].push_back(edge(v, c));
 86         }
 87         S = num["Calgary"], T = num["Fredericton"];
 88         bfs();
 89         
 90         printf("Scenario #%d\n", t);
 91         cin>>Q;
 92         while(Q--)
 93         {
 94             int tmp; cin>>tmp;
 95             int ans = INF;
 96             for(int i = 1; i <= tmp + 1; i++)
 97                 ans = min(ans, f[T][i]);
 98             if(ans == INF) puts("No satisfactory flights");
 99             else printf("Total cost of flight(s) is $%d\n", ans);
100         }
101         
102     }
103     return 0;
104 }

 

posted @ 2018-06-20 10:59  俺是小程  阅读(172)  评论(0编辑  收藏  举报