• (最短路+A*搜索)POJ 2449


    题意:

    给一个DAG,要求s到t的第K短路,很经典的问题。


    分析:

    我们可以看到k<=1000,这个值不是很大,我可以想到直接bfs走遍所有情况,最多也就有1000中情况,但是1000个点显然会M。

    既然是要求k短路,也就是说最终计算出来的到达t的花费必然是递增的,也就是说我们在搜索的时候肯定要用到优先队列。

    这时应该很明显了,必然需要A*搜索,但是A*的预估函数依然是个问题,我想了很久没有想到,后来偶然在一本书上发现了这题。

    书上的处理是用dijsktra预处理每点到t的最短路,就是每个状态到达目标的预估值。

    恍然大悟。

    但是怎么求每个点到t的最短路的,我们知道dijsktra的中间变量dist计算的是s到每个顶点的最短路,我们只需要把原图构建一个反向图,

    计算t到每个点的最短路,就是原图每个点到t的最短路,这时候再进行普通的A*就行了。

    然而本题一堆坑。

    1、你需要再A*的时候判连通,不然将死循环

    2、需要特殊处理从自己走到自己的情况,初始的0显然不算在k短路内。


    代码:

      1 #include <set>
      2 #include <map>
      3 #include <list>
      4 #include <cmath>
      5 #include <queue>
      6 #include <stack>
      7 #include <vector>
      8 #include <bitset>
      9 #include <string>
     10 #include <cctype>
     11 #include <cstdio>
     12 #include <cstring>
     13 #include <cstdlib>
     14 #include <iostream>
     15 #include <algorithm>
     16 // #include <unordered_map>
     17 
     18 using namespace std;
     19 
     20 typedef long long ll;
     21 typedef unsigned long long ull;
     22 typedef pair<int, int> pii;
     23 typedef pair<ull, ull> puu;
     24 
     25 #define inf (0x3f3f3f3f)
     26 #define lnf (0x3f3f3f3f3f3f3f3f)
     27 #define eps (1e-9)
     28 #define fi first
     29 #define se second
     30 
     31 bool sgn(double a, string select, double b) {
     32     if(select == "==")return fabs(a - b) < eps;
     33     if(select == "!=")return fabs(a - b) > eps;
     34     if(select == "<")return a - b < -eps;
     35     if(select == "<=")return a - b < eps;
     36     if(select == ">")return a - b > eps;
     37     if(select == ">=")return a - b > -eps;
     38 }
     39 
     40 
     41 //--------------------------
     42 
     43 const ll mod = 1000000007;
     44 const int maxn = 1010;
     45 
     46 //use to bfs
     47 struct Node {
     48     int v, c;
     49     Node(int _v = 0, int _c = 0) {
     50         v = _v, c = _c;
     51     }
     52     bool operator<(const Node &a)const {
     53         return c > a.c;
     54     }
     55 };
     56 
     57 //first is 'v' , second is 'cost'
     58 vector<pii> edge[maxn];
     59 vector<pii> zedge[maxn];
     60 bool vis[maxn];
     61 int dist[maxn];
     62 
     63 void addedge(int u, int v, int w) {
     64     edge[v].push_back(make_pair(u, w));
     65     zedge[u].push_back(make_pair(v, w));
     66 }
     67 
     68 // id from 1
     69 void dijkstra_heap(int n, int start) {
     70     memset(vis, 0, sizeof(vis));
     71     for(int i = 1; i <= n; i++) dist[i] = inf;
     72     priority_queue<Node> que;
     73     while(!que.empty())que.pop();
     74     dist[start] = 0;
     75     que.push(Node(start, 0));
     76     Node tmp;
     77     while(!que.empty()) {
     78         tmp = que.top();
     79         que.pop();
     80         int u = tmp.v;
     81         if(vis[u])continue;
     82         vis[u] = true;
     83         for(int i = 0; i < edge[u].size(); i++) {
     84             int v = edge[u][i].fi;
     85             int cost = edge[u][i].se;
     86             if(!vis[v] && dist[v] > dist[u] + cost) {
     87                 dist[v] = dist[u] + cost;
     88                 que.push(Node(v, dist[v]));
     89             }
     90         }
     91     }
     92 }
     93 
     94 struct anode {
     95     int v;
     96     int f, g, h;
     97     anode(int _v = 0, int _f = 0, int _g = 0, int _h = 0) {
     98         v = _v, f = _f, g = _g, h = _h;
     99     }
    100     bool operator<(const anode &a)const {
    101         return f > a.f;
    102     }
    103 };
    104 
    105 int n, m;
    106 int s, t, k;
    107 
    108 bool Astar(int start) {
    109     if(s == t) {
    110         k++;
    111     }
    112     if(dist[start] == inf) {
    113         return false;
    114     }
    115     priority_queue<anode> que;
    116     while(!que.empty())que.pop();
    117     int num = 0;
    118     que.push(anode(start, dist[start], 0, dist[start]));
    119     while(!que.empty()) {
    120         anode tmp = que.top();
    121         que.pop();
    122         if(tmp.v == t) {
    123             num++;
    124             // printf("%d
    ", tmp.g );
    125         }
    126         if(num >= k) {
    127             printf("%d
    ", tmp.g );
    128             return true;
    129         }
    130         int u = tmp.v;
    131         for(int i = 0; i < zedge[u].size(); i++) {
    132             int v = zedge[u][i].fi;
    133             int cost = zedge[u][i].se;
    134             int g = tmp.g + cost;
    135             int h = dist[v];
    136             int f = g + h;
    137             que.push(anode(v, f, g, h));
    138         }
    139     }
    140     return false;
    141 }
    142 
    143 
    144 void solve() {
    145     while(~scanf("%d%d", &n, &m)) {
    146         for(int i = 1; i <= n; i++) {
    147             edge[i].clear();
    148             zedge[i].clear();
    149         }
    150         int u, v, w;
    151         for(int i = 0; i < m; i++) {
    152             scanf("%d%d%d", &u, &v, &w);
    153             addedge(u, v, w);
    154         }
    155         scanf("%d%d%d", &s, &t, &k);
    156         dijkstra_heap(n, t);
    157         if(!Astar(s)) {
    158             puts("-1");
    159         }
    160     }
    161 }
    162 
    163 int main() {
    164 
    165 #ifndef ONLINE_JUDGE
    166     freopen("1.in", "r", stdin);
    167     freopen("1.out", "w", stdout);
    168 #endif
    169     // iostream::sync_with_stdio(false);
    170     solve();
    171     return 0;
    172 }
  • 相关阅读:
    Maven 那点事儿
    maven pom文件详解
    Maven Missing artifact jar
    JVM调优总结 -Xms -Xmx -Xmn -Xss
    LoadRunner做性能测试 从设计到分析执行
    linux内核参数注释与优化
    tcpdump详解
    [转]Linux服务器上11种网络连接状态 和 TCP三次握手/四次挥手详解
    MSM--Memcached_Session_Manager介绍及使用
    黏性Session和非黏性Session
  • 原文地址:https://www.cnblogs.com/tak-fate/p/6665291.html
Copyright © 2020-2023  润新知