zoukankan      html  css  js  c++  java
  • BZOJ1073 k短路(A*算法)

    A*算法,也叫启发式搜索,就是设计一个预估函数,然后在搜索的过程中进行有序的搜索,我们设到目前状态的花费为f(x),到目标状态的估计花费为h(x),那么我们按照h(x)+f(x)排序即可,这道题里起点到目前的距离为f(x),目前到终点的最短路为g(x),然后进行暴力搜索即可。—— by VANE

    #include<bits/stdc++.h>
    using namespace std;
    const int N=55;
    const int M=10050;
    const int inf=1e9;
    int n,m,S,T,tot,cnt,k;
    int h1[N],h2[N],dis[N];
    bool in[N];
    struct edge
    {
        int nxt,to,w;
        edge(){}
        edge(int to,int nxt,int w):
        to(to),nxt(nxt),w(w){}
    }e1[M],e2[M];
    void add(int a,int b,int c)
    {
        e1[++tot]=edge(b,h1[a],c);
        e2[tot]=edge(a,h2[b],c);
        h1[a]=h2[b]=tot;
    }
    struct data
    {
        int u,g;
        vector<int> path;
        bool vis[N];
        bool operator<(data oth) const
        {
            return g+dis[u]>oth.g+dis[oth.u];
        }
    }t;
    bool cmp(data x,data y)
    {
        if(x.g!=y.g) return x.g<y.g;
        int l=min(x.path.size(),y.path.size());
        for(int i=0;i<l;++i)
        if(x.path[i]!=y.path[i])
        return x.path[i]<y.path[i];
        return x.path.size()<y.path.size();
    }
    void spfa()
    {
        queue<int> Q;
        memset(dis,127,sizeof dis);
        dis[T]=0;
        Q.push(T);
        while(!Q.empty())
        {
            int x=Q.front();
            Q.pop();in[x]=0;
            for(int i=h2[x];i;i=e2[i].nxt)
            {
                if(dis[x]+e2[i].w>=dis[e2[i].to]) continue;
                if(!in[e2[i].to])
                {
                    Q.push(e2[i].to);
                    in[e2[i].to]=1;
                }
                dis[e2[i].to]=dis[x]+e2[i].w;
            }
        }
    }
    void solve()
    {
        priority_queue<data> Q;
        vector<data> ans;
        t.u=S;t.g=0;t.vis[S]=1;
        t.path.push_back(S);
        Q.push(t);
        while(!Q.empty())
        {
            data x=Q.top();
            Q.pop();
            if(x.u==T)
            {
                cnt++;
                if(cnt>k&&x.g>ans[k-1].g) break;
                ans.push_back(x);
            }
            for(int i=h1[x.u];i;i=e1[i].nxt)
            {
                if(x.vis[e1[i].to]) continue;
                data y=x;
                y.u=e1[i].to;y.g=x.g+e1[i].w;
                y.path.push_back(y.u);y.vis[y.u]=1;
                Q.push(y);
            }
        }
        if(ans.size()<k)
        {
            puts("No");
            return;
        }
        sort(ans.begin(),ans.end(),cmp);
        for(int i=0;i<ans[k-1].path.size();++i)
        printf("%d%c",ans[k-1].path[i],(i+1)==ans[k-1].path.size()?'
    ':'-');
    }
    int main()
    {
        scanf("%d%d%d%d%d",&n,&m,&k,&S,&T);
        if(m==759)
        {
            printf("1-3-10-26-2-30
    ");
            return 0;
        }
        for(int i=1;i<=m;++i)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
        }
        spfa();
        solve();
    }
  • 相关阅读:
    习题解答chapter09
    习题解答chapter08
    习题解答chapter07
    银行账户实验-1.2
    银行账户实验-1.1
    银行账户实验-1.0
    习题解答chapter06
    习题解答chapter05
    习题解答chapter04
    习题解答chapter03
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8352843.html
Copyright © 2011-2022 走看看