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

    看了这里 http://blog.csdn.net/acm_cxlove/article/details/8679230的分析之后自己又按照自己的模板写了一遍,算是对spfa又加深了一步认识(以前真是只会用,没想太多)。

    又来当一次搬运工,一点点进步。

    题意是这样的:A个村庄,B个城堡,共有K次穿越的机会,且不能经过城堡或者穿越距离必须不超过L,否则必须停下来,当然,不能再道路中间停下来。

    按照大大的思路是这样做的:对于每出队的一个结点u,均有两种方式继续走下去,一中是使用一次穿越,另一种是不使用。这样对于使用穿越的情况,必须考虑所有满足d[u][v]<=L的点v,然后dp[v][k+1] = min(dp[v][k+1],dp[u][k])转移方程,其中dp[u][k]表示从起点A+B走到u使用k次穿越经过的最小距离;对于不使用穿越的情况就和普通spfa一样转移。

    然后怎样判断由一个节点到另一个节点能够满足d[u][v]<=L呢,这中间会涉及到城堡不能穿越,可以求出使用spfa求出(i,j)之间的最短距离,对于j是城堡的时候就不把j入队,这样中间有城堡的两个节点d[i][j]是不能直接穿越的,也就是d[i][j] == inf.

    然后下面是我写的代码:

    (思路也可以去原po那里看)

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <climits>
      4 #include <cstring>
      5 #include <cstdlib>
      6 #include <cmath>
      7 #include <vector>
      8 #include <queue>
      9 #include <algorithm>
     10 #define esp 1e-6
     11 #define pb push_back
     12 #define in  freopen("in.txt", "r", stdin);
     13 #define out freopen("out.txt", "w", stdout);
     14 #define print(a) printf("%d
    ",(a));
     15 #define bug puts("********))))))");
     16 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
     17 #define inf 0x3f3f3f3f
     18 using namespace std;
     19 typedef long long  LL;
     20 typedef vector<int> VI;
     21 typedef vector<int>:: iterator IT;
     22 #define N 2000
     23 #define INF 200000
     24 struct EDGE
     25 {
     26     int i, c;
     27     EDGE *ani,*next;
     28 }   *Edge[N], E[INF];
     29 int d[N][N], inq[N], dp[N][20];
     30 int cnt, A, B, M, L, K;
     31 void add(int i, int j, int c, EDGE &e1, EDGE &e2)
     32 {
     33     e1.i = j, e1.c = c, e1.ani = &e2, e1.next = Edge[i], Edge[i] = &e1;
     34     e2.i = i, e2.c = c, e2.ani = &e1, e2.next = Edge[j], Edge[j] = &e2;
     35     cnt += 2;
     36 }
     37 void init(void)
     38 {
     39     cnt = 0;
     40     memset(Edge, 0, sizeof(Edge));
     41 //    memset(d, 0x0f, sizeof(d));
     42 }
     43 void preprocess(void)
     44 {
     45     memset(d, 0x3f, sizeof(d));
     46     for(int i = 1; i <= A + B; i++)
     47     {
     48         queue<int> q;
     49         memset(inq, 0, sizeof(inq));
     50         inq[i] = 1;
     51         d[i][i] = 0;
     52         q.push(i);
     53         while(!q.empty())
     54         {
     55             int u = q.front();
     56             int v;
     57             q.pop();
     58             inq[u] = 0;
     59             for(EDGE * p = Edge[u]; p; p = p->next)
     60                 if(d[i][v = p->i] > d[i][u] + p->c)
     61                 {
     62                     if(d[i][v] = d[i][u] + p->c, v <= A && !inq[v])
     63                         inq[v] = 1, q.push(v);
     64                 }
     65         }
     66     }
     67 }
     68 void spfa(int s, int end)
     69 {
     70     memset(dp, 0x3f, sizeof(dp));
     71     memset(inq, 0, sizeof(inq));
     72     queue<int> q;
     73     inq[s] = 1;
     74     dp[s][0] = 0;
     75     q.push(s);
     76     while(!q.empty())
     77     {
     78         int u = q.front(), v;
     79         q.pop();
     80         inq[u] = 0;
     81         for(EDGE *p = Edge[u]; p; p = p->next)
     82             for(int k = 0; k <= K; k++)
     83                 if(dp[u][k] < inf)
     84                 {
     85                     if(dp[v = p->i][k] > dp[u][k] + p->c)
     86                         if(dp[v][k] = dp[u][k] + p->c, !inq[v])
     87                             inq[v] = 1, q.push(v);
     88                     if(k - K)
     89                     {
     90                         for(v = 1; v <= A + B; v++)
     91 //                        if(dp[u][k] < inf)
     92                             if(d[u][v] <= L && dp[u][k] < dp[v][k+1])
     93                                 if(dp[v][k+1] = dp[u][k], !inq[v])
     94                                     inq[v] = 1, q.push(v);
     95                     }
     96                 }
     97     }
     98 }
     99 int main(void)
    100 {
    101 
    102     int T;
    103     for(int t = scanf("%d", &T); t <= T; t++)
    104     {
    105         init();
    106         scanf("%d%d%d%d%d", &A, &B, &M, &L, &K);
    107         for(int i = 1; i <= M; i++)
    108         {
    109             int u, v, w;
    110             scanf("%d%d%d", &u, &v, &w);
    111             add(u, v, w, E[cnt], E[cnt + 1]);
    112         }
    113         preprocess();
    114         spfa(A+B, 1);
    115         int ans = inf;
    116         for(int k = 0; k <= K; k++)
    117             ans = min(dp[1][k], ans);
    118         printf("%d
    ", ans);
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    Spring Boot 使用 Dom4j XStream 操作 Xml
    Spring Boot 使用 JAX-WS 调用 WebService 服务
    Spring Boot 使用 CXF 调用 WebService 服务
    Spring Boot 开发 WebService 服务
    Spring Boot 中使用 HttpClient 进行 POST GET PUT DELETE
    Spring Boot Ftp Client 客户端示例支持断点续传
    Spring Boot 发送邮件
    Spring Boot 定时任务 Quartz 使用教程
    Spring Boot 缓存应用 Memcached 入门教程
    ThreadLocal,Java中特殊的线程绑定机制
  • 原文地址:https://www.cnblogs.com/rootial/p/SPFA-DP.html
Copyright © 2011-2022 走看看