zoukankan      html  css  js  c++  java
  • UVa10269 Adventure of Super Mario

    不错的最短路题.一开始没想到如何处理 "Mario NEVER super runs through a Castle" 这个条件,然后大力分类讨论.

    在写了将近70行的状态扩展后,我放弃了.

    实际上,这题没有这么麻烦.这个条件限制只用在floyd预处理的时候就可以解决了.

    具体来说, 在floyd的时候,限制中转点为乡村

            for(int k = 1; k <= A; k++)
                for(int i = 1; i <= (A + B); i++)
                    for(int j = 1; j <= (A + B); j++)
    

     根据算法的性质, 这样所有路径除起点, 终点之外的点就都在乡村了.

    用了这个非常妙的做法以后, 就不难写出状态的扩展了.

    这里用的是dijkstra

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <queue>
     7 using namespace std;
     8 const int MAXN = 1e2 + 20;
     9 const int INF = 0x3f3f3f3f;
    10 
    11 int A, B, M, L, K;
    12 int d[MAXN][MAXN], f[MAXN][12];
    13 bool vis[MAXN][12];
    14 
    15 struct edge
    16 {
    17     int to, cost;
    18 };vector<edge> g[MAXN];
    19 struct state
    20 {
    21     int pos, time, k;
    22     state(int u = 0, int t = 0, int k = 0) :
    23     pos(u), time(t), k(k) {}
    24     bool operator >(const state &rhs) const{
    25         return time > rhs.time;
    26     }
    27 };
    28 
    29 void init()
    30 {
    31     memset(d, 0x3f, sizeof(d));
    32     memset(f, 0x3f, sizeof(f));
    33     memset(vis, false, sizeof(vis));
    34     for(int i = 1; i <= (A + B); i++) g[i].clear();
    35 }
    36 
    37 void floyd()
    38 {
    39     for(int i = 1; i <= (A + B); i++) d[i][i] = 0;
    40         for(int k = 1; k <= A; k++)
    41             for(int i = 1; i <= (A + B); i++)
    42                 for(int j = 1; j <= (A + B); j++)
    43                     if(d[i][k] != INF && d[k][j] != INF)
    44                         d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
    45 }
    46 
    47 inline bool tension(const int &st, int &lg)
    48 {
    49     return st < lg ? (lg = st, true) : false;
    50 }
    51 
    52 int bfs()
    53 {
    54     priority_queue<state, vector<state>, greater<state> > q;
    55     f[(A + B)][0] = 0;
    56     q.push(state((A + B), 0, 0));
    57 
    58     while(!q.empty())
    59     {
    60         state u = q.top(); q.pop();
    61         if(u.pos == 1) return u.time;
    62         if(vis[u.pos][u.k]) continue;
    63         vis[u.pos][u.k] = true;
    64         for(int i = 0; i < (int) g[u.pos].size(); i++)
    65         {
    66             edge &e = g[u.pos][i];
    67             if(tension(u.time + e.cost, f[e.to][u.k]))
    68                 q.push(state(e.to, f[e.to][u.k], u.k));
    69         }
    70 
    71         if(u.k < K)
    72         for(int i = 1; i <= (A + B); i++)
    73             if(d[i][u.pos] <= L && tension(u.time + 0, f[i][u.k + 1]))
    74                 q.push(state(i, f[i][u.k + 1], u.k + 1));
    75     }
    76     return rand();
    77 }
    78 
    79 int main()
    80 {
    81     //freopen("10269.in", "r", stdin);
    82     //freopen("10269.out", "w", stdout);
    83     int T; cin>>T;
    84     while(T--)
    85     {
    86         cin>>A>>B>>M>>L>>K;init();
    87         for(int i = 1, u, v, c; i <= M; i++)
    88         {
    89             scanf("%d%d%d", &u, &v, &c);
    90             d[u][v] = d[v][u] = c;
    91             g[u].push_back((edge){v, c});
    92             g[v].push_back((edge){u, c});
    93         }
    94         floyd();
    95         printf("%d
    ", bfs());
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    9.17(day11)
    9.14(day10)
    9.13(day9)
    9.12(day8)
    mysql 的存储过程
    MySQL 子查询与多表联合查询
    MySQL 函数
    MySQL 的查询
    MySQL的约束
    MySQL 表的增删改查操作
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/9202154.html
Copyright © 2011-2022 走看看