zoukankan      html  css  js  c++  java
  • POJ 2449 求第K短路

    第一道第K短路的题目 QAQ

    拿裸的DIJKSTRA + 不断扩展的A* 给2000MS过了

    题意:大意是 有N个station 要求从s点到t点 的第k短路 (不过我看题意说的好像是从t到s 可能是出题人写错了)

    从这题中还真的学到了很多
    1.第k短路的算法 A* 还有用边表实现dij


    (注:以下部份资料来源于网上)
    所谓A*就是启发是搜索 说白了就是给搜索一个顺序使得搜索更加合理减少无谓的搜索. 如何来确定搜索的顺序?..也就是用一个值来表示 这个值为f[n]..每次搜索取f[x]最小的拓展 那么这个f[n]=h[n]+g[n]
    其中f(n) 是节点n的估价函数,g(n)是在状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。在这里主要是h(n)体现了搜索的启发信息,因为g(n)是已知的。如果说详细 点,g(n)代表了搜索的广度的优先趋势。但是当h(n) >> g(n)时,可以省略g(n),而提高效率。

    A*算法的估价函数可表示为:   
      f’(n) = g’(n) + h’(n)   
    这里,f’(n)是估价函数,g’(n)是起点到终点的最短路径值,h’(n)是n到目标的最短路经的启发值。由 于这个f’(n)其实是无法预先知道的,所以我们用前面的估价函数f(n)做近似。g(n)代替g’(n),但 g(n)>=g’(n) 才可(大多数情况下都是满足的,可以不用考虑),h(n)代替h’(n),但h(n)<=h’(n)才可(这一点特别的重 要)。可以证明应用这样的估价函数是可以找到最短路径的,也就是可采纳的。我们说应用这种估价函数的 最好优先算法就是

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <math.h>
      5 #include <iostream>
      6 #include <stack>
      7 #include <queue>
      8 #include <algorithm>
      9 
     10 #define ll long long
     11 using namespace std;
     12 const int INF = 0x3f3f3f3f;
     13 const int MAXN = 1111;
     14 
     15 struct vertex{
     16     int sum, h, pos;
     17     bool operator < (vertex a) const{
     18         return a.sum + a.h < sum + h;
     19     }
     20 };
     21 struct sc{
     22        int u, v, w, next;
     23 }line1[MAXN*MAXN],line2[MAXN*MAXN];
     24 
     25 int link1[MAXN],link2[MAXN],h[MAXN],times[1001];
     26 int n, m, s, e, k;
     27 bool vis[MAXN];
     28 priority_queue <vertex> que;
     29 
     30 void init(){
     31     memset(link1, 0, sizeof(link1));
     32     memset(link2, 0, sizeof(link2));
     33     memset(vis,0,sizeof(vis));
     34     memset(h,0x3f,sizeof(h));//h函数初始值为最大
     35     while (!que.empty()) que.pop();
     36     memset(times,0,sizeof(times));
     37 }
     38 
     39 void djikstra(){
     40     int i,k,p;
     41     h[e] = 0;
     42     for (p = 1; p <= n; ++p){
     43         k = 0;
     44         for (i = 1; i <= n; ++i)
     45             if (!vis[i] && (!k||h[i]<h[k])) k = i;
     46         vis[k] = true;
     47         k = link2[k];
     48         while (k){
     49             if (h[line2[k].v] > h[line2[k].u] + line2[k].w)
     50                 h[line2[k].v] = h[line2[k].u] + line2[k].w;
     51             k = line2[k].next;
     52         }
     53     }
     54 }
     55 
     56 int Astar(){
     57     int t;
     58     vertex g,temp;
     59     g.pos = s;
     60     g.sum = 0;
     61     g.h = h[s];
     62     que.push(g);
     63     
     64     if (s==e) ++k;
     65     while (!que.empty()){
     66         g = que.top();//每次取估价函数值最小的节点
     67         que.pop();
     68         ++times[g.pos];
     69         if (times[g.pos] == k && g.pos == e) return g.sum + g.h;
     70         if (times[g.pos] > k) continue;
     71 
     72         t = link1[g.pos];
     73         while (t){//扩展,并把其加入优先队列即openlist
     74             temp.sum = g.sum + line1[t].w;
     75             temp.h = h[line1[t].v];
     76             temp.pos = line1[t].v;
     77             que.push(temp);
     78             t = line1[t].next;
     79         }
     80     }
     81     return -1;
     82 }
     83 
     84 int main(){
     85     int i, j;
     86     while(cin >> n >> m){
     87         init();
     88         for (i = 1; i <= m; ++i){
     89             cin >> line1[i].u >> line1[i].v >> line1[i].w;
     90             line1[i].next = link1[line1[i].u];//记录与节点u有直接边的节点
     91             link1[line1[i].u] = i;
     92 
     93             line2[i].u = line1[i].v;
     94             line2[i].v = line1[i].u;
     95             line2[i].w = line1[i].w;
     96             line2[i].next = link2[line2[i].u];
     97             link2[line2[i].u] = i;
     98         }
     99         cin >> s >> e >> k;
    100         djikstra();
    101         cout << Astar() << endl;
    102     }
    103     return 0;
    104 }
  • 相关阅读:
    Eclipse打jar包的方法
    Eclipse中SVN插件的安装
    无法远程访问 MySql Server
    TCP(Socket基础编程)
    安装淘宝镜像cnpm时出现问题及解决方案
    搭建vue脚手架---vue-cli
    padding和margin设置成百分比
    响应式布局
    响应式网页:用em,rem设置网页字体大小自适应
    url两次编码
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/3892970.html
Copyright © 2011-2022 走看看