zoukankan      html  css  js  c++  java
  • poj 2449 Remmarguts' Date【第K短路】

    题目

    题意:求 点s 到 点t 的 第 k 短 路的距离;

    估价函数=当前值+当前位置到终点的距离

    f(n)=g(n)+h(n);     g(n)表示g当前从s到p所走的路径的长度,      h(n)‘启发式函数’,表示为终点t到其余一点p的路径长度;

    (1)将有向图的所有边反向,以原终点t为源点,求解t到所有点的最短距离; 
    (2)新建一个优先队列,将源点s加入到队列中; 
    (3)从优先级队列中弹出f(p)最小的点p,如果点p就是t,则计算t出队的次数; 
    如果当前为t的第k次出队,则当前路径的长度就是s到t的第k短路的长度,算法结束; 
    否则遍历与p相连的所有的边,将扩展出的到p的邻接点信息加入到优先级队列;

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <vector>
    using namespace std;
    
    const int Maxn = 10010;
    const int INF = 1e9;
    
    struct node{
        int to,val;
        node(){}
        node(int a,int b)
        {
            to = a; val = b;
        }
    };
    
    vector<node> adj[Maxn],_adj[Maxn];
    
    int n,m,k;
    bool vis[Maxn];
    int dis[Maxn];
    
    void AddEdge(int x,int y,int val)
    {
        adj[x].push_back(node(y,val));
        _adj[y].push_back(node(x,val));//反向存图
    }
    void Dijkstra(int s,int t)
    {
        priority_queue<int, vector<int>,greater<int> > q;
        while(!q.empty()) q.pop();
        for(int i=1;i<=n;i++)
            vis[i]=false,dis[i]=INF;
        vis[t]=true;dis[t]=0;q.push(t);
        int u,len;
        while(!q.empty())
        {
            u = q.top(); q.pop();
            len = _adj[u].size();
            for(int i=0;i<len;i++)
            {
                node v = _adj[u][i];
                if(dis[v.to]>dis[u]+v.val)
                {
                    dis[v.to]=dis[u]+v.val;
                    if(!vis[v.to])
                    {
                        q.push(v.to);
                        vis[v.to]=true;
                    }
                }
            }
            vis[u]= false;
        }
    }
    struct Anode{
        int h,g,id;
        Anode(int a,int b,int c){h=a;g=b;id=c;}
        bool operator < (Anode a) const{
            return h+g > a.h + a.g;
        }
    };
    priority_queue<Anode> Q;
    int Astar(int s,int t)    //A*算法
    {
        while(!Q.empty()) Q.pop();
        Q.push(Anode(0,dis[s],s));
        int len,num;
        num=0;
        while(!Q.empty())
        {
            Anode u = Q.top();
            Q.pop();
            if(u.id==t) ++num;
            if(num>=k) return u.h;
            len = adj[u.id].size();
            for(int i=0;i<len;i++)
            {
                node v = adj[u.id][i];
                Q.push(Anode(u.h+v.val,dis[v.to],v.to));
            }
        }
        return -1;
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=-1)
        {
            for(int i=0;i<Maxn;i++)
                adj[i].clear(),_adj[i].clear();
            int x,y,v,s,t;
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d%d",&x,&y,&v);
                AddEdge(x,y,v);
            }
            scanf("%d%d%d",&s,&t,&k);
            if(s==t) k++;
            Dijkstra(s,t);
            printf("%d
    ",Astar(s,t));
        }
        return 0;
    }
    /*
    2 2
    1 2 5
    2 1 4
    1 2 2
    */
    
  • 相关阅读:
    redis持久化,主从及数据备份
    验证redis的快照和AOF
    Erlang中日志管理
    erlang tcp发包速度测试
    树(234树插入查找显示)
    JDBC(初步试用)
    树(二叉树的插入删除查找遍历)
    哈希表(链地址法插入删除)
    哈希表-再哈希法插入删除
    哈希表-线性探测插入删除
  • 原文地址:https://www.cnblogs.com/qie-wei/p/10160152.html
Copyright © 2011-2022 走看看