• POJ2449Remmarguts' Date


    题意:求K短路

    先介绍A*算法:

    A*算法是一种启发式的搜索,不是纯粹的盲目式搜索,A*算法中有个估价算法g(n),对于每个点而言,都有一个g(n)和h(n)来确定的f(n),实际上就是以f(n)为参考权值来确定搜索的方向,在这里,我们的h(n)表示的是从s点出发到n这个点现在走过的路径长度,而g(n)表示的是从n到e的最短长度的大小,那么就确定了搜索的优先性,这里的A*算法的估价函数g(n)是完美估价,搜索的方向一定是对的。

    分析:K短路可以用A*+spfa求。。先求出终点到各个点的最短距离d[1~n],这个变是A*算法的估价函数d[1~n];

    建图的时候建一个正向的一个反向的,反向图用来求估价终点到每个点的距离,即为搜索的估价函数。

    注意:若s==t,则k++, 因为题目要求必须走过路径。

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define MAXN 1005
    #define INF 1000000000
    using namespace std;
    int n,m,e;
    struct eee{
        int v;//正向图的终止点
        int u;//反向图的终止点
        int next;//正向图的下一条边
        int next1;//反向图的下一条边
        int w;//权值
    }edge[100*MAXN];
    
    struct node{
        int v;
        int f;
        int g;
        bool operator <(const node &a)const{
            if(f==a.f)return g>a.g;
            else return f>a.f;
        }
    };
    int d[MAXN];//d[v]表示的是终点到v的距离,即估价函数g
    int first[MAXN],first1[MAXN],vis[MAXN];
    priority_queue<node>pq;
    queue<int> que;
    void add(int u,int v,int w){
        edge[e].u=u;
        edge[e].w=w;
        edge[e].v=v;
        edge[e].next=first[u];
        first[u]=e;
        edge[e].next1=first1[v];
        first1[v]=e++;
    }
    void init(int n){
        memset(first,-1,sizeof(first));
        memset(vis,0,sizeof(vis));
        memset(first1,-1,sizeof(first1));
        e=0;
    }
    void spfa(int s){//求估价函数
        while(!que.empty())que.pop();
        for(int i=1;i<=n;i++)d[i]=INF;
        d[s]=0;vis[s]=1;
        que.push(s);
        while(!que.empty()){
            int u=que.front();
            que.pop();
            vis[u]=0;
            for(int i=first1[u];i!=-1;i=edge[i].next1){
                int v=edge[i].u;
                if(d[v]>d[u]+edge[i].w){
                    d[v]=d[u]+edge[i].w;
                    if(!vis[v]){
                        que.push(v);
                        vis[v]=1;
                    }
                }
            }
        }
    }
    int a_start(int s,int t,int k){
        while(!pq.empty())pq.pop();
        int cnt=0;
        if(s==t)k++;
        node a;
        a.v=s,a.g=0;
        a.f=a.g+d[s];
        pq.push(a);
        while(!pq.empty()){
            node b=pq.top();
            pq.pop();
            if(b.v==t)cnt++;
            if(cnt==k)return b.g;
            for(int i=first[b.v];i!=-1;i=edge[i].next){
                int v=edge[i].v;
                a.g=b.g+edge[i].w;
                a.f=a.g+d[v];
                a.v=v;
                pq.push(a);
            }
        }
        return -1;
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)==2){
            init(n);
            int a,b,c;
            for(int i=1;i<=m;i++){
                scanf("%d%d%d",&a,&b,&c);
                add(a,b,c);
            }
            int s,t,k;
            scanf("%d%d%d",&s,&t,&k);
            spfa(t);
            if(d[s]==INF)printf("-1\n");
            else
            printf("%d\n",a_start(s,t,k));
        }
        return 0;
    }
  • 相关阅读:
    Windows XP下Qemu模拟器上OpenSolaris的安置
    图解SMC下Solaris用户图形经管(下)
    Solaris 10的功能
    在Solaris 下用DVD光盘保存数据(1)
    Solaris10下载、安设和设置装备摆设(2)
    Solaris 10密码忘记打点法子
    对Unix任事器进行性能监测(上)
    Solaris效力打点东西 SMF快速入门指南(3)
    Solaris 10主动安顿DVD运用步骤
    Solaris效劳经管器材 SMF疾速入门指南(2)
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2682402.html
Copyright © 2020-2023  润新知