电路维修
https://www.acwing.com/activity/content/code/content/3329525/
这个题宽搜+图论变形+最短路的结合,好题
非特殊点可以匹配四个方向,分别是左上,左下,右上,右下,一个点到这些方向只能是\//\,如果匹配成功边权是0,不匹配就说明需要转化开关,边权是1,需要用循环来实现这个匹配过程,所以三个偏移量一定要对应了,然后就是边权为0和1的最短路问题,可以用双端宽搜,也就是特殊的dijkstra
其他的就没什么好注意的了
看代码
#include<iostream> #include<deque> #include<cstring> using namespace std; typedef pair<int,int> PAII; const int N=1000; char ch[N][N]; int dist[N][N]; bool st[N][N]; int n,m; int dx[4]={-1,-1,1,1},dy[4]={-1,1,1,-1};//一个点可以到达另一个点的坐标 int ix[4]={-1,-1,0,0},iy[4]={-1,0,0,-1};//此时的斜线正跨过哪一个格子 char cs[]="\\/\\/"; //可以转化为无向图,除了边界,这些点都指向四个方向。三个偏移量一定要对应了!!! int bfs()//双端队列,dij的一种特殊情况 { memset(dist,0x3f,sizeof(dist)); memset(st,false,sizeof(st)); deque<PAII> q; q.push_back({0,0}); dist[0][0]=0; while(q.size()) { auto t=q.front(); q.pop_front();//从队头取出来一个元素 int a=t.first,b=t.second; if(st[a][b]) continue;//与dij一样,防止用过的数来继续更新(没啥意义) else st[a][b]=true; for(int i=0;i<4;i++) { int xx=a+dx[i],yy=b+dy[i];//点 int gx=a+ix[i],gy=b+iy[i];//格点 if(xx<0||yy<0||xx>n||yy>m) continue;//出边界就跳过 int d=dist[a][b]+(ch[gx][gy]!=cs[i]); if(dist[xx][yy]>d)//更新 { dist[xx][yy]=d; if(ch[gx][gy]!=cs[i]) q.push_back({xx,yy});//看权值如果是0插入队头 else q.push_front({xx,yy});//1就插入队尾 } } } if(dist[n][m]>0x3f3f3f3f/2) return -1; else return dist[n][m]; } int main(){ int T; cin>>T; while(T--) { cin>>n>>m; for(int i=0;i<n;i++) for(int j=0;j<m;j++) cin>>ch[i][j]; int t=bfs(); if(t==-1) cout<<"NO SOLUTION"<<endl; else cout<<t<<endl; } return 0; } /* 看成权值是0和1的最短路问题,如果符合就是0,不符合需要转就是1 两个权值的典型要用双端队列bfs,本质是dijkstra,其实就是它的一个特殊情况 从队头取出,如果是0就插入队头,1就插入队尾,不断更新,过程和dijskta差不多 本题:算的是(0,0)到(n,m)点!!的最短路径 格点只是来比较看看权值是0还是1 */
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具