zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ", ans);
    100         }
    101         
    102     }
    103     return 0;
    104 }
  • 相关阅读:
    LeetCode–打印从1到最大的n位数
    常用十大算法(十)— 踏棋盘算法
    常用十大算法(九)— 弗洛伊德算法
    常用十大算法(八)— 迪杰斯特拉算法
    LeetCode–组合
    LeetCode–组合总和
    5513. 连接所有点的最小费用 kruskal
    152. 乘积最大子数组 dp
    1567. 乘积为正数的最长子数组长度 dp
    5481. 得到目标数组的最少函数调用次数. 位运算
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/9202732.html
Copyright © 2011-2022 走看看