A*初步+ K短路

求第k条最短路的问题
首先我们可以想到一个比较暴力的办法,直接BFS,使用优先队列从源点进行宽度优先遍历,当第K次遍历到终点t时,所求的长度就是第k短路。但是这种算法在运行过程中会产生多个状态,点过多时会爆栈。
A*算法,结合了启发式方法和形式化方法,通过一个估价函数f(h)来估价图中当前点p到终点的距离,并由此决定它的搜索方向。
估价函数 = 当前值 + 当前位置到终点的距离
f(p) = g(p) + h(p)
h(p)可以用从终点开始跑单源最短路处理出来。然后利用优先队列,和BFS进行搜索,终点k次出队,就是第k条最短路。
点数在1000以内ACMoK
附上模版和模版题http://poj.org/problem?id=2449

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 1010;
const int inf = 0x3f3f3f3f;
int dist[MAXN];  //dist[i]记录此时源点到i的最短距离
bool vis[MAXN];  //标记点是否在队列中
int cnt[MAXN];   //cnt[i]记录结点入队的次数,判断是否存在负权环
vectorint, int> >mp[MAXN*100],mp2[MAXN*100];//mp存原图,mp2寸反向图
struct node {
    int point;
    int g, f;
    friend bool operator<(node a, node b){
        return a.f==b.f?a.g>b.g:a.f>b.f;
    }
};
int A_star(int s, int e, int n, int k){
    priority_queue q;
    int cnt=0;
    if(s==e){
        k++;
    }
    if(dist[s]==inf){//终点不可达到
        return -1;
    }
    node node1;
    node1.point=s;
    node1.g=0;
    node1.f=dist[s]+node1.g;
    q.push(node1);
    while (!q.empty()) {
        node cc=q.top();
        q.pop();
        if (cc.point==e) {
            cnt++;
        }
        if (cnt==k) {//求出第k短路
            return cc.g;
        }
        for (int i=0; ireturn -1;
}
bool spfa(int n, int s){//注意这里s的实参是e
    memset(dist, 0x3f, sizeof(dist));
    queue<int>  q;
    while (!q.empty()) {
        q.pop();
    }
    q.push(s);
    dist[s]=0;
    cnt[s]+=1;
    vis[s]=true;
    while (!q.empty()) {
        int u=q.front();
        q.pop();
        vis[u]=false;
        for (int i=0; iint point=mp2[u][i].first;
            if (dist[point]>dist[u]+mp2[u][i].second) {
                dist[point]=dist[u]+mp2[u][i].second;//松弛操作
                if(!vis[point]){//如果此点不在队列中
                    vis[point]=true;
                    q.push(point);
                    cnt[point]++;
                    if (cnt[point]>n) {
                        return false;
                    }
                }
            }
        }
    }
    return true;
}
int main(){

    int n,m;
    int x,y,z;
    cin>>n>>m;
    while (m--) {
        cin>>x>>y>>z;
        mp[x].push_back(make_pair(y, z));
        mp2[y].push_back(make_pair(x, z));
    }
    int s,e,k;
    cin>>s>>e>>k;
    spfa(n, e);
    int res=A_star(s, e, n, k);
    cout<return 0;
}










你可能感兴趣的:(杂记)