• POJ 2449 Remmarguts' Date(A*K短路) xgtao


    Remmarguts' Date

    给出原点和终点,给出一个有向图,问起点到终点的第k短的路有多长。

    首先确定这是一道搜索的题目,然而Gemini说这是一道A*,既然是A*那么就有估计值和实际值,估计值不好在搜索的时候计算,那么就先把距离预处理出来,就从终点到起点Dijsktra,最后再从起点A*,当终点进入优先队列k次时,那么所走的路径一定是第k短路。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    using namespace std;
    
    const int inf = (1<<31)-1;
    const int maxn = 1010;
    const int maxm = 100010;
    #define clr(a,b) memset(a,b,sizeof(a))
    int n,m;
    int u,v,w,s,t,k;
    int dis[maxn],done[maxn],cnt[maxn];
    struct Edge{
    	int u,v,w;
    	Edge *nxt;
    }meo[2*maxm],*head[maxn],*cur,*rehead[maxn];
    struct node{
    	int dis,u;
    	bool operator < (const node &rhs)const{
    		return dis>rhs.dis;
    	}
    };
    struct star{
    	int d,u;
    	bool operator < (const star &rhs)const{
    		return d+dis[u]>rhs.d+dis[rhs.u];//*****
    	}
    };
    void adde(int u,int v,int w,Edge *f[]){
    	cur->v = v;
    	cur->w = w;
    	cur->nxt = f[u];
    	f[u] = cur++;
    //	printf("!%d %d %d\n",u,v,w);
    }
    
    void dijkstra(int s){
    	priority_queue<node>q;
    	for(int i = 1;i <= n;++i)dis[i] = inf;
    	dis[s] = 0;
    	q.push((node){dis[s],s});
    	while(!q.empty()){
    		node p = q.top();
    		q.pop();
    		int u = p.u;
    		if(done[u])continue;
    		done[u] = true;
    		for(Edge *it = rehead[u];it;it = it->nxt){
    			int v = it->v;
    			if(dis[v] > dis[u]+it->w){
    				dis[v] = dis[u] + it->w;
    				q.push((node){dis[v],v});
    			}
    		}
    	}
    //	for(int i = 1;i <= n;++i)printf("%d ",dis[i]);puts("");
    }
    
    int AStar(int s,int t){
    	if(dis[s] == inf)return -1;
    	if(s == t)++k;//*****
    	priority_queue <star> q;
    	q.push((star){0,s});
    	while(!q.empty()){
    		star p = q.top();
    		q.pop();
    		cnt[p.u]++;
    		if(cnt[t] == k)return p.d;
    		for(Edge *it = head[p.u];it;it = it->nxt){
    			q.push((star){it->w+p.d,it->v});
    		}
    	}
    	return -1;
    }
    
    int main(){
    	cur = meo;
    	scanf("%d%d",&n,&m);
    	for(int i = 1;i <= m;++i){
    		scanf("%d%d%d",&u,&v,&w);
    		adde(u,v,w,head);
    		adde(v,u,w,rehead);
    	}
    	scanf("%d%d%d",&s,&t,&k);
    	dijkstra(t);
    	printf("%d\n",AStar(s,t));
    	return 0;
    }
    

      

  • 相关阅读:
    持续交付知易行难,想做成这事你要理解这几个关键点
    运维需要懂产品和运营吗?
    云计算和AI时代,运维应该如何做好转型?
    从谷歌CRE谈起,运维如何培养服务意识?
    谷歌SRE运维模式解读
    如何打造好运维组织架构?
    如何在CMDB中落地应用的概念?
    有了CMDB,为什么还需要应用配置管理?
    Vue视图渲染原理解析,从构建VNode到生成真实节点树
    10个Vue开发技巧助力成为更好的工程师(二)
  • 原文地址:https://www.cnblogs.com/xgtao984/p/5690494.html
Copyright © 2020-2023  润新知