zoukankan      html  css  js  c++  java
  • k短路算法

    k短路算法

    求解k短路用到了A* 算法,A* ( A star )算法,又称启发式搜索算法,与之相对的,dfs与bfs都成为盲目型搜索;即为带有估价函数的优先队列BFS称为A*算法。

    该算法的核心思想为设计一个估价函数,估价函数需要满足下面几个准则:

    1:设当前状态state到目标状态所需的估计值为(f(state))

    2:在未来的搜索中,实际求出的从当前状态state到目标状态的最小代价为(g(state))

    3:对于任意的(state),应该有(f(state)<=g(state))

    之后每次取出“当前代价+未来估价最小的状态,最终更新到目标状态上,就能得到最优解。

    A*算法的应用非常广,被广泛应用于最优路径求解和一些策略设计问题中。

    首先跑一下Dijkstra或者SPFA反向求一下终点到各个点的最短路,然后A*求出k短路,上代码:

    #include<cstdio>
    #include<cstring>
    #include<queue>
    
    using namespace std;
    const int maxn=1e5+10;
    const int inf=0x3f3f3f3f; 
    int head[maxn],head1[maxn],tot,tot1;
    int n,m,s,t,k,dis[maxn]; 
    struct Edge{
    	int nex,to,val;
    }edge[maxn],edge1[maxn];
    struct  node{
    	int to,f,g; 				//估价函数和实际代价
    	friend bool operator <(const node& a,const node& b){
    		if(a.f==b.f)	return a.g>b.g;
    		return a.f>b.f;
    	}
    }now,temp;
    bool vis[maxn];
    void add(int from,int to,int val)
    {
    	edge[++tot].to=to;
    	edge[tot].val=val;
    	edge[tot].nex=head[from];
    	head[from]=tot;
    }
    void add1(int from,int to,int val)
    {
    	edge1[++tot1].to=to;
    	edge1[tot1].val=val;
    	edge1[tot1].nex=head1[from];
    	head1[from]=tot1;
    }
    queue<int> q;
    bool spfa(int s)
    {
    	for(int i=1;i<=n;++i){
    		dis[i]=inf;
    		vis[i]=false;
    	}
    	vis[s]=1;
    	dis[s]=0;
    	while(!q.empty())	q.pop();
    	q.push(s);
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		vis[u] = 0;
    		for(int i=head1[u];i!=-1;i=edge1[i].nex){
    			int v=edge1[i].to;
    			if(dis[v]>dis[u]+edge[i].val){
    				dis[v]=dis[u]+edge[i].val;
    				if(vis[v])	continue;
    				vis[v] = 1;
    				q.push(v);
    			}
    		}
    	}
    	return true;
    }
    priority_queue<node> que;
    int A_star()
    {
    	int cnt=0;
    	while(!que.empty())	que.pop();
    	if(!spfa(t)||dis[s]==inf)	return -1;
    	if(s==t) 	++k; 			//起点跟终点相同,不能算dis=0这一条
    	now.to=s; 
    	now.g=0;
    	now.f=now.g+dis[now.to];
    	que.push(now);
    	while(!que.empty()){
    		now = que.top();
    		que.pop();
    		if(now.to==t)	cnt++;
    		if(cnt==k)	return now.g;
    		for(int i=head[now.to];i!=-1;i=edge[i].nex){
    			temp.to=edge[i].to; 
    			temp.g=now.g+edge[i].val;
    			temp.f=temp.g+dis[temp.to];
    			que.push(temp);
    		}
    	}
    	return -1;
    }
     
    int main()
    {
    	while(scanf("%d %d",&n,&m)==2)
    	{
    		for(int i=1;i<=n;++i){
    			head[i]=head1[i]=-1;
    		}
    		tot=tot1=0;
    		for(int i=1;i<=m;++i){
    			int a,b,val;
    			scanf("%d %d %d",&a,&b,&val);
    			add(a,b,val);
    			add1(b,a,val);
    		}
    		scanf("%d %d %d",&s,&t,&k);
    		printf("%d
    ",A_star());
    	}
    }
    
  • 相关阅读:
    参考Shiro的自定义基于Spring的AOP横切模式
    Spring-@Value获取配置文件内容
    BeanPostProcessor Bean实例的初始化前后的自定义修改
    两台Linux主机之间免密scp复制文件及远程启动关闭Tomcat
    Shiro Realm领域
    test
    Linux 安装Oracle数据库
    Shiro Authorizer授权器
    HDU 1079 Calendar Game (博弈)
    MooFest POJ
  • 原文地址:https://www.cnblogs.com/StungYep/p/12252248.html
Copyright © 2011-2022 走看看