首页 > 编程语言 >第K短路(A*算法 启发式搜索算法)

第K短路(A*算法 启发式搜索算法)

时间:2023-05-29 11:35:03浏览次数:66  
标签:JOJO real int 短路 搜索算法 leq edge 启发式 dis


【启发式算法】

定义函数 h[x] = g[x] +f[x]; 其中 g[x] 是x结点的真实值,f[x]是x结点的估计剩余代价值,h[x]就是当前方案的总估计值。

在BFS过程中,以最优价值优先遍历,可以减小时间复杂度,并简化问题。A*算法的优势就是,对当前结点做一个价值估计,取出堆中最优的结点进行下一次遍历。

在求第K短路时,最无脑的思路就是,以起点s展开BFS,进行搜索,所有到达终点e的路径中,第k小的即为第k短路。借助A*算法的思想,处于结点u时,设已走过的路程为g[u],剩下的最快到达终点的路长为f[u],把g[u]+f[u]看做估价值,其实就是,已经处于当前点u,总路长再短也就g[u]+f[u]了,所以按这个值优先bfs遍历,在终点e处就能依次得到递增的路长。

【例题--2018icpc沈阳网络赛D Made In Heaven】

One day in the jail, F·F invites Jolyne Kujo (JOJO in brief) to play tennis with her. However, Pucci the father somehow knows it and wants to stop her. There are NN spots in the jail and MM roads connecting some of the spots. JOJO finds that Pucci knows the route of the former (K-1)(K−1)-th shortest path. If Pucci spots JOJO in one of these K-1K−1 routes, Pucci will use his stand Whitesnake and put the disk into JOJO's body, which means JOJO won't be able to make it to the destination. So, JOJO needs to take the KK-th quickest path to get to the destination. What's more, JOJO only has TT units of time, so she needs to hurry.

JOJO starts from spot SS, and the destination is numbered EE. It is possible that JOJO's path contains any spot more than one time. Please tell JOJO whether she can make arrive at the destination using no more than TT units of time.

Input

There are at most 5050 test cases.

The first line contains two integers NN and MM (1 \leq N \leq 1000, 0 \leq M \leq 10000)(1≤N≤1000,0≤M≤10000). Stations are numbered from 11 to NN.

The second line contains four numbers S, E, KS,E,Kand TT ( 1 \leq S,E \leq N1≤S,E≤N, S \neq ES≠E, 1 \leq K \leq 100001≤K≤10000, 1 \leq T \leq 1000000001≤T≤100000000 ).

Then MM lines follows, each line containing three numbers U, VU,V and WW (1 \leq U,V \leq N, 1 \leq W \leq 1000)(1≤U,V≤N,1≤W≤1000) . It shows that there is a directed road from UU-th spot to VV-th spot with time WW.

It is guaranteed that for any two spots there will be only one directed road from spot AA to spot BB (1 \leq A,B \leq N, A \neq B)(1≤A,B≤N,A≠B), but it is possible that both directed road <A,B><A,B> and directed road <B,A><B,A> exist.

All the test cases are generated randomly.

Output

One line containing a sentence. If it is possible for JOJO to arrive at the destination in time, output "yareyaredawa" (without quote), else output "Whitesnake!" (without quote).

样例输入复制

2 2
1 2 2 14
1 2 5
2 1 4

样例输出复制

yareyaredawa

题目来源

ACM-ICPC 2018 沈阳赛区网络预赛

【题意】

有向图,n点m边,求s->e是否存在k中方案的路径,使得路程<=T

【分析】

第k短路小于等于T即可。

从终点到起点求一遍单源最短路,作为估计剩余值。

从起点向终点BFS,A*思想,已走路+剩余最短路作为估计值。

【代码】

/****
***author: winter2121
****/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX=4e4+5;
const int INF=0x3f3f3f3f;

struct graph{
    struct node{
        int t,next,len;
    }edge[MAX];
    int head[MAX],cnt;
    void init(int n)
    {
        memset(head,-1,sizeof(head[0])*(n+1));cnt=0;
    }
    void addedge(int u,int v,int len)
    {
        edge[cnt]=node{v,head[u],len};
        head[u]=cnt++;
    }
}G,R;

int n,m,s,e,k,T;
ll dis[MAX];
bool inq[MAX];
void diji(graph &G,int s,int e)
{
    for(int i=0;i<=n;i++)dis[i]=INF,inq[i]=0;
    dis[s]=0;
    queue<int>q;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front(); q.pop();
        inq[u]=0;
        for(int i=G.head[u];~i;i=G.edge[i].next)
        {
            int v=G.edge[i].t;
            if(dis[v]>dis[u]+G.edge[i].len)
            {
                dis[v]=dis[u]+G.edge[i].len;
                if(!inq[v])
                    inq[v]=1,q.push(v);
            }
        }
    }
}

struct Anode{   //优先h=real+need,f相等时按实际值real小的
    ll real,need;//实际值,预算
    int id;
    friend bool operator<(Anode a,Anode b)
    {
       // if(a.f+a.g==b.f+b.g)return a.g>b.g;
        return a.need+a.real>b.need+b.real;
    }
};
ll Astar(graph &G,int s,int e,int k)
{
    if(s==e)k++; //最短路必为0,而题目中最短路必须是正数,故排除0
    if(dis[s]==INF)return -1; //se没有通路,会导致在s的连通块里一直转圈
    int cnt=0;
    priority_queue<Anode> q;
    q.push(Anode{0,dis[s],s});
    while(!q.empty())
    {
        Anode u=q.top(); q.pop();
        if(u.id==e)
        {
            cnt++;
            if(k==cnt)return u.real;
        }
        for(int i=G.head[u.id];~i;i=G.edge[i].next)
        {
            int v=G.edge[i].t;
            q.push(Anode{u.real+G.edge[i].len,dis[v],v});
        }
    }
    return -1;
}
int main()
{
    while(~scanf("%d%d%d%d%d%d",&n,&m,&s,&e,&k,&T))
    {
        G.init(n);
        R.init(n);
        int a,b,c;
        for(int i=1;i<=m;++i)
        {
            scanf("%d%d%d",&a,&b,&c);
            G.addedge(a,b,c);
            R.addedge(b,a,c);
        }
        diji(R,e,s);
        int A=Astar(G,s,e,k);
        if(A>=0&&A<=T)printf("yareyaredawa\n");
        else printf("Whitesnake!\n");
    }
    return 0;
}

 

标签:JOJO,real,int,短路,搜索算法,leq,edge,启发式,dis
From: https://blog.51cto.com/u_16125110/6369243

相关文章

  • 设计可以求最短路径的图类
    类包括根据顶点数和边初始化的构造函数,添加边,求两点最短路径等函数1.邻接矩阵classGraph{private:vector<vector<int>>graph;public:Graph(intn,vector<vector<int>>&edges){graph.resize(n,vector<int>(n,INT_MAX/2));for(auto&......
  • POJ 1797 Heavy Transportation(迪杰斯特拉最短路变形)
    传送门题意分析:Hugo想要扩展他的公司,他有起重机要到目的地,到达目的地有很多条路径,但是,每一条路都有相应承重量,现在需要找出到达目的地的最大承重道路的承重质量。解题分析:首先,每一条路径的承重量取决于承重量最小的那条道路(短板效应),所以就是找所有路径的最小值,然后选择最小值最大的......
  • 2-3 改写二分搜索算法
    设a[0:n-1]是已排好序的数组。请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素的位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。测试数据(自己写的):61234567输出:i=5,j=-16123456-1输出:i=-1,j=......
  • 最短路总结
    单源最短路Bellman-FordSPFADijkstraH-Dijkstra思路遍历全边,直到不变宽搜渐进,入队再更找最近点,更新邻点,找完不再用取负入队,大根堆找点,其余相同负边权能能否否判负环能能否否时间复杂度O(nm)O(km~nm)O(m+n^2)O(mlogn)适用于为什么不用SP......
  • Johnson 全源最短路
    全源最短路,换一种说法就是n个单源最短路,可以用n次Bellman-Ford或SPFA,非负边权还可以用Dijkstra,可是有负边权用前两个算法还是慢,如果我们能把负边权映射成非负边权的话,一切就都好办了这里我们引入一个虚拟结点,它和所有点的初始距离都是0,然后,我们求出来这个结点和其他店的最短路h,然......
  • Floyed 全源最短路
    全源最短路,顾名思义,就是任意两点之间的最短路floyed的思路就是每次选一个点k,如果k不在u和v路径上,就不改变,如果k在u和v的路径上,进行松弛操作d[u][v]=min(d[u][v],d[u][k]+d[k][v])例题洛谷B3647【模板】Floyd算法#include<iostream>#defineforup(i,l,r)for(inti=l;i<=r;......
  • 浅谈 树上带权最长最短路径,决策包容性与点分树
    树上带权最长最短路径,决策包容性与点分树\(\text{preface}\)最近学习了点分树相关的内容,也碰巧见识到了许多……树上路径问题(非负权),最长或是最短,有的可以用点分治(树)解决,有的可以用线段树解决,有的需要深层次挖掘性质,就在这里做一个小小地总结了一些另类的方法。1.树上带权最长......
  • 搜索算法
    //DPS(深度搜索)//n-皇后问题//方法一(与数字全排列相似)#include<bits/stdc++.h>usingnamespacestd;constintN=80;intn,res=0;charQ[N][N];boolcow[N],dg[N],rdg[N];//dg,rdg是对角线和反对角线,cow是列;voiddfs(intu){if(u==n){res++;......
  • Bellman-Ford 单源最短路
    单源最短路,顾名思义,就是从一个起点到其余点的最短距离Bellman-Ford算法的思路是进行至多n-1轮的更新,每次遍历所有的边,进行松弛操作d[v]=min(d[v],d[u]+w);Bellman-Ford算法可以处理有负边权的图,也可以判负环,只要在第n轮还能进行松弛操作,说明存在负环例题洛谷P3371【模板】单......
  • 启发式算法在三维装箱问题上的应用
    启发式算法的出现时间比较难以确定,因为很多算法的提出都是在不同的领域和不同的时间段内,而且随着时间的推移,这些算法也在不断地完善和发展。以下是一些比较有代表性的启发式算法及其出现时间:1953年,模拟退火算法(SimulatedAnnealing,SA)模拟退火算法是一种基于固体物理学中固体退火......