zoukankan      html  css  js  c++  java
  • uva 10269(floyd+Dijkstra)

    积攒已久的题目了,果断前两星期怎么做做不对,隔一段时间一做就对了。

    题意:马里奥要求从结点1到a+b的最短路。前提是他有一种靴子能在任意距离小于l的结点之间飞(经过的路上必须为村庄,耗时为零),结点标号前a个为村庄,靴子只能用k次。

    思路:这道题用floyd初始化+Dijkstra+dp就搞定了。刷了一段时间最短路,这样的做法已经做过几遍了。floyd初始化任意两个可飞到的结点的距离。Dijkstra处理最短路只要在dis数组后加一维状态就可。每次转移的时候分两部分,一部分是不用靴子就和正常的Dij一样,在一种是根据初始化的距离判断能否用靴子。

    代码如下:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <cmath>
      6 #include <algorithm>
      7 #include <queue>
      8 #include <stack>
      9 #include <vector>
     10 #include <map>
     11 #include <set>
     12 #define MP(a, b) make_pair(a, b)
     13 #define PB(a) push_back(a)
     14 
     15 using namespace std;
     16 
     17 typedef long long ll;
     18 typedef struct {int p, k;}S;
     19 typedef pair<int, int> pii;
     20 typedef pair<int, S> pis;
     21 
     22 const int INF = 0x3f3f3f3f;
     23 const double eps = 1E-6;
     24 const int LEN = 110;
     25 int a, b, m, l, k, n;
     26 int idis[LEN][LEN], dis[LEN][LEN];
     27 vector<pii> Map[LEN];
     28 struct cmp
     29 {
     30     bool operator() (pis x, pis y){return x.first > y.first;}
     31 };
     32 
     33 inline S MS(int x, int y){S ret;ret.p = x,ret.k = y;return ret;}
     34 
     35 void read()
     36 {
     37     int x, y ,v;
     38     scanf("%d%d%d%d%d", &a, &b, &m, &l, &k);
     39     n = a+b;
     40     memset(idis, 0x3f, sizeof idis);
     41     for(int i=0; i<LEN; i++)Map[i].clear();
     42     for(int i=0; i<m; i++){
     43         scanf("%d%d%d", &x, &y, &v);
     44         idis[x][y] = idis[y][x] = v;
     45         Map[x].PB(MP(y, v));
     46         Map[y].PB(MP(x, v));
     47     }
     48 }
     49 
     50 void floyd()
     51 {
     52     for(int i=1; i<=n; i++)idis[i][i] = 0;
     53     for(int k=1; k<=a; k++){
     54         for(int i=1; i<=n; i++){
     55             for(int j=1; j<=n; j++){
     56                 idis[i][j] = min(idis[i][j], idis[i][k]+idis[k][j]);
     57             }
     58         }
     59     }
     60 }
     61 
     62 void Dijkstra(int s)
     63 {
     64     priority_queue<pis, vector<pis>, cmp> q;
     65     int vis[LEN][LEN] = {0};
     66     for(int i=1; i<=n; i++){
     67         for(int j=0; j<=k; j++){
     68             dis[i][j] = INF;
     69         }
     70     }
     71     dis[s][0] = 0;
     72     q.push(MP(dis[s][0], MS(s,0)));
     73     while(!q.empty()){
     74         pis nvex = q.top(); q.pop();
     75         S ts = nvex.second;
     76         int nv = ts.p, nk = ts.k;
     77         if(vis[nv][nk])continue;
     78         vis[nv][nk] = 1;
     79         for(int i=0; i<Map[nv].size(); i++){
     80             int x = Map[nv][i].first, y = Map[nv][i].second;
     81             if(dis[x][nk] > dis[nv][nk] + y){
     82                 dis[x][nk] = dis[nv][nk] + y;
     83                 q.push(MP(dis[x][nk], MS(x, nk)));
     84             }
     85         }
     86         for(int i=1; i<=n; i++){
     87             int x = i;
     88             if(idis[nv][x]<=l && dis[x][nk+1] > dis[nv][nk]){
     89                 dis[x][nk+1] = dis[nv][nk];
     90                 q.push(MP(dis[x][nk+1], MS(x, nk+1)));
     91             }
     92         }
     93     }
     94 }
     95 
     96 int main()
     97 {
     98 //    freopen("in.txt", "r", stdin);
     99 
    100     int T;
    101     scanf("%d", &T);
    102     while(T--){
    103         read();
    104         floyd();
    105         Dijkstra(1);
    106         int ans = INF;
    107         for(int i=0; i<=k; i++)ans = min(ans, dis[n][i]);
    108         printf("%d
    ", ans);
    109     }
    110     return 0;
    111 }
    View Code
    奔跑吧!少年!趁着你还年轻
  • 相关阅读:
    高并发网络编程之epoll详解
    位操作实现加减乘除四则运算
    堆和栈的区别
    IT思想类智力题
    C/C++基础总结
    数据库总结
    面试网络总结
    Windows内存管理和linux内存管理
    面试操作系统总结
    数据结构与算法
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3517963.html
Copyright © 2011-2022 走看看