当前位置: 首页 > news >正文

(板子)A* astar算法,AcWing第k短路+八数码 带注释

目录

第K短路

八数码


第K短路

给定一张 NN 个点(编号 1,2…N1,2…N),MM 条边的有向图,求从起点 SS 到终点 TT 的第 KK 短路的长度,路径允许重复经过点或边。

注意: 每条最短路中至少要包含一条边。

输入格式

第一行包含两个整数 NN 和 MM。

接下来 MM 行,每行包含三个整数 A,BA,B 和 LL,表示点 AA 与点 BB 之间存在有向边,且边长为 LL。

最后一行包含三个整数 S,TS,T 和 KK,分别表示起点 SS,终点 TT 和第 KK 短路。

输出格式

输出占一行,包含一个整数,表示第 KK 短路的长度,如果第 KK 短路不存在,则输出 −1−1。

数据范围

1≤S,T≤N≤10001≤S,T≤N≤1000,
0≤M≤1040≤M≤104,
1≤K≤10001≤K≤1000,
1≤L≤1001≤L≤100

输入样例:

2 2
1 2 5
2 1 4
1 2 2

输出样例:

14

 

#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <queue>
#define x first;
#define y second
using namespace std;
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
const int N=1010,M=200010;
int n,m,S,T,K;
int h[N],rh[N],e[M],w[M],ne[M],idx;
int dist[N],cnt[N];//dist[i]表示点i到终点的估计值,也是最短距离,cnt[N]表示这个点已经是第几次到达了
bool st[N];//标记这个点是否到达过(求返图最短路的时候)
void add(int h[],int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void dijkstra()//求返图最短路
{
    priority_queue<PII,vector<PII>,greater<PII> >heap;
    heap.push({0,T});//当前点到起点的距离,当前点
    memset(dist,0x3f,sizeof(dist));
    dist[T]=0;
    while(!heap.empty())
    {
        auto t=heap.top();
        heap.pop();
        int ver=t.y;
        if(st[ver]) continue;
        st[ver]=true;
        for(int i=rh[ver];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[ver]+w[i])
            {
                dist[j]=dist[ver]+w[i];
                heap.push({dist[j],j});
            }
        }
    }
}
int astar()
{
    priority_queue<PIII,vector<PIII>,greater<PIII> > heap;
    heap.push({dist[S],{0,S}});//三个值分别为估值函数的值=真实值+估计值,真实距离,当前遍历到哪个点
    while(!heap.empty())
    {
        auto t=heap.top();
        heap.pop();
        int ver=t.y.y,distance=t.y.x;
        cnt[ver]++;
        if(cnt[T]==K) return distance;
        for(int i=h[ver];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(cnt[j]<K)
            heap.push({distance+w[i]+dist[j],{distance+w[i],j}});
        }
    }
    return -1;
}
int main()
{
    scanf("%d%d",&n,&m);
    memset(h,-1,sizeof(h));
    memset(rh,-1,sizeof(rh));
    for(int i=0;i<m;i++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        add(h,a,b,c);
        add(rh,b,a,c);
    }
    scanf("%d%d%d",&S,&T,&K);
    if(S==T)
    K++;
    dijkstra();//对反向图求每个点到终点色的最短距离,求出估计值
    printf("%d\n",astar());
    return 0;
}

八数码

在一个 3×33×3 的网格中,1∼81∼8 这 88 个数字和一个 X 恰好不重不漏地分布在这 3×33×3 的网格中。

例如:

1 2 3
X 4 6
7 5 8

在游戏过程中,可以把 X 与其上、下、左、右四个方向之一的数字交换(如果存在)。

我们的目的是通过交换,使得网格变为如下排列(称为正确排列):

1 2 3
4 5 6
7 8 X

例如,示例中图形就可以通过让 X 先后与右、下、右三个方向的数字交换成功得到正确排列。

交换过程如下:

1 2 3   1 2 3   1 2 3   1 2 3
X 4 6   4 X 6   4 5 6   4 5 6
7 5 8   7 5 8   7 X 8   7 8 X

把 X 与上下左右方向数字交换的行动记录为 udlr

现在,给你一个初始网格,请你通过最少的移动次数,得到正确排列。

输入格式

输入占一行,将 3×33×3 的初始网格描绘出来。

例如,如果初始网格如下所示:

1 2 3 
x 4 6 
7 5 8 

则输入为:1 2 3 x 4 6 7 5 8

输出格式

输出占一行,包含一个字符串,表示得到正确排列的完整行动记录。

如果答案不唯一,输出任意一种合法方案即可。

如果不存在解决方案,则输出 unsolvable

输入样例:

2  3  4  1  5  x  7  6  8 

输出样例

ullddrurdllurdruldr
#include <bits/stdc++.h>
#include <cstring>
#include <unordered_map>
#include <queue>
using namespace std;
int f(string state)//计算当前状态的曼哈顿距离,作为估计值
{
    int res=0;
    for(int i=0;i<state.size();i++)
    if(state[i]!='x')
    {
        int t=state[i]-'1';
        res+=abs(i/3-t/3)+abs(i%3-t%3);
    }
    return res;
}
string bfs(string start)
{
    int dx[4]={-1,0,1,0};
    int dy[4]={0,1,0,-1};
    char op[4]={'u','r','d','l'};
    string end="12345678x";
    unordered_map<string ,int>dist;
    unordered_map<string,pair<string,char> > prev;//当前状态是通过前一个字符串的某个操作转移过来的
    priority_queue<pair<int,string>,vector<pair<int,string>>,greater<pair<int,string > > >heap;
    heap.push({f(start),start});
    dist[start]=0;//dist是准确值,不断被更新
    while(!heap.empty())
    {
        auto t=heap.top();
        heap.pop();
        string state=t.second;
        if(state==end)
        break;
        int step=dist[state];
        int x,y;
        for(int i=0;i<state.size();i++)//寻找x的位置
        {
            if(state[i]=='x')
            {
                x=i/3;
                y=i%3;
                break;
            }
        }
        string source=state;
        for(int i=0;i<4;i++)//遍历四个方向
        {
            int a=x+dx[i];
            int b=y+dy[i];
            if(a>=0&&a<3&&b>=0&&b<3)
            {
                swap(state[x*3+y],state[a*3+b]);
                if(!dist.count(state)||dist[state]>step+1)
                {
                    dist[state]=step+1;
                    prev[state]={source,op[i]};
                    heap.push({dist[state]+f(state),state});
                }
                swap(state[x*3+y],state[a*3+b]);
            }
        }
    }
    string res;
    while(end!=start)//组合答案
    {
        res+=prev[end].second;
        end=prev[end].first;
    }
    reverse(res.begin(),res.end());
    return res;
}
int main()
{
    string g,c,seq;
    while(cin>>c)
    {
        g+=c;
        if(c!="x") seq+=c;
    }
    int t=0;
    for(int i=0;i<seq.size();i++)//查找逆序对
    {
        for(int j=i+1;j<seq.size();j++)
        {
            if(seq[i]>seq[j])
            t++;
        }
    }
    if(t%2) puts("unsolvable");
    else cout<<bfs(g)<<endl;
    return 0;
}

 

相关文章:

  • DOMjudge——Ubuntu18.04安装教程
  • JavaEE——文件内容的读写
  • 人脑能否重启?
  • 软件测试基础(五)—— Liunx基础命令行
  • 基于群智能的路径规划算法(三)------遗传算法
  • 到底怎么能精准挑到“报恩榴莲”?
  • C# 窗体进度条
  • 【opencv-c++】鼠标事件
  • STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级)
  • ijkplayer播放器剖析(四)音频解码与音频输出机制分析
  • 本地web项目如何使用外网访问?教你轻松使用cpolar在windows搭建内网穿透
  • MySQL复合查询
  • 你需要的导航网站,这里都有
  • [SV]SystemVerilog中指定打印格式
  • 长期主义就是坚持重复的做一件事?
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • C# 免费离线人脸识别 2.0 Demo
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • C++11: atomic 头文件
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • Cookie 在前端中的实践
  • ES6简单总结(搭配简单的讲解和小案例)
  • Javascripit类型转换比较那点事儿,双等号(==)
  • Linux gpio口使用方法
  • PAT A1050
  • webgl (原生)基础入门指南【一】
  • 给初学者:JavaScript 中数组操作注意点
  • 前端存储 - localStorage
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 新手搭建网站的主要流程
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​学习一下,什么是预包装食品?​
  • #13 yum、编译安装与sed命令的使用
  • #Java第九次作业--输入输出流和文件操作
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • $.ajax,axios,fetch三种ajax请求的区别
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (十三)Flask之特殊装饰器详解
  • .Net IE10 _doPostBack 未定义
  • .net mvc部分视图
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • ?php echo $logosrc[0];?,如何在一行中显示logo和标题?
  • @RunWith注解作用
  • [ C++ ] STL---string类的模拟实现
  • [ MSF使用实例 ] 利用永恒之蓝(MS17-010)漏洞导致windows靶机蓝屏并获取靶机权限
  • []AT 指令 收发短信和GPRS上网 SIM508/548
  • [202209]mysql8.0 双主集群搭建 亲测可用
  • [BUG] Hadoop-3.3.4集群yarn管理页面子队列不显示任务
  • [BZOJ3223]文艺平衡树