zoukankan      html  css  js  c++  java
  • T105289 【模板】A*

    题目地址


    注意点:

    • 起点和终点相同时,k需要提前++.
    • Node内的比较函数应当使用:当前费用+预估费用.

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int MAXN=3e3,MAXM=3e5;
    struct Edge_First{//反向图 
    	int from,to,nxt,w;
    }e_First[MAXM];
    int head_First[MAXN],edgeCnt_First=1;
    void addEdge_First(int u,int v,int w){
    	e_First[++edgeCnt_First].from=u;
    	e_First[edgeCnt_First].to=v;
    	e_First[edgeCnt_First].w=w;
    	e_First[edgeCnt_First].nxt=head_First[u];
    	head_First[u]=edgeCnt_First;
    }
    int s,t,k;//起点 终点 第k短路 
    struct Node_First{
    	int v,dis;
    	bool operator <(Node_First another)const{
    		return dis>another.dis;
    	}
    };
    int f[MAXN];//估价函数 
    void dijkstra(){
    	memset(f,0x3f,sizeof(f));
    	priority_queue<Node_First> q;
    	q.push(Node_First{t,0});
    	f[t]=0;
    	while(!q.empty()){
    		Node_First nowNode=q.top();
    		q.pop();
    		int nowU=nowNode.v;
    		if(nowNode.dis!=f[nowU])continue;
    		for(int i=head_First[nowU];i;i=e_First[i].nxt){
    			int nowV=e_First[i].to;
    			if(f[nowV]>f[nowU]+e_First[i].w){
    				f[nowV]=f[nowU]+e_First[i].w;
    				q.push(Node_First{nowV,f[nowV]});
    			}
    		}
    	}
    }
    struct Edge{
    	int from,to,w,nxt;
    }e[MAXM];
    int head[MAXN],edgeCnt=1;
    void addEdge(int u,int v,int w){
    	e[++edgeCnt].from=u;
    	e[edgeCnt].to=v;
    	e[edgeCnt].w=w;
    	e[edgeCnt].nxt=head[u];
    	head[u]=edgeCnt;
    }
    struct Node{
    	int v,f,g; 
    	bool operator <(Node another)const{
    		return f+g>another.f+another.g;
    	}
    };
    int updateTime[MAXN];
    int ans;
    bool Astar(){
    	priority_queue<Node> q;
    	q.push(Node{s,f[s],0});
    	while(!q.empty()){
    		Node nowNode=q.top();
    		q.pop();
    		int nowU=nowNode.v;
    		updateTime[nowU]++;
    		if(nowU==t&&updateTime[nowU]==k){
    			ans=nowNode.g;
    			return 1;
    		}
    		for(int i=head[nowU];i;i=e[i].nxt){
    			int nowV=e[i].to;
    			q.push(Node{nowV,f[nowV],nowNode.g+e[i].w});
    		}
    	}
    	return 0;
    }
    int main(){
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++){
    		int a,b,l;
    		scanf("%d%d%d",&a,&b,&l);
    		addEdge_First(b,a,l);//反向边
    		addEdge(a,b,l);//正向边 
    	}
    	scanf("%d%d%d",&s,&t,&k);
    	if(s==t)k++;
    	dijkstra();
    	if(Astar()){
    		cout<<ans<<endl;
    	}else cout<<"-1"<<endl;
    	return 0;
    }
    

      

  • 相关阅读:
    OpenCV 立体匹配 (自带程序)
    OpenCV 双目标定 ( 自带的例子)
    容器
    OpenCV 多边形逼近
    C++ 读取文件
    OpenCV 快速连通区域分析
    图像任意旋转
    OpenCV 模板匹配函数matchTemplate详解
    二十一:scrapy中设置下载延时与自动限速
    二十、scrapy中的Request对象和Response对象
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11741030.html
Copyright © 2011-2022 走看看