狼抓兔子
思路
将面看成点,然后将边转换成面和面之间的边,然后跑一遍最短路,就可以了。
但是具体那个是起点,那个是终点,是这么进行确定的,我还不太确定。
代码
#include <bits/stdc++.h> using namespace std; #define int long long const int M=3e6+5; using pii=pair<int,int>; int n,m; int h[M],ne[M<<1],e[M<<1],w[M<<1],tot=1; void add(int from,int to,int w1,int w2) { e[++tot]=to; w[tot]=w1; ne[tot]=h[from]; h[from]=tot; e[++tot]=from;w[tot]=w2; ne[tot]=h[to]; h[to]=tot; } int dis[M]; bool vis[M]; int S=M-2,T=M-1; int dij() { memset(dis,0x7f,sizeof(dis)); dis[S]=0; priority_queue<pii>q; q.push({0,S}); while(!q.empty()) { int now=q.top().second; q.pop(); if(vis[now])continue; vis[now]=1; if(now==T)return dis[now]; for(int i=h[now];i;i=ne[i]) { int to=e[i]; if(dis[to]>dis[now]+w[i]) dis[to]=dis[now]+w[i],q.push({-dis[to],to}); } } return -1; } int id(int x,int y) { return (x-1)*(m-1)+y; } signed main() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<m;j++) { int wi,x,y;cin>>wi; if(i==1)x=S,y=j; else if(i==n)x=T,y=id(2*(i-1),j); else x=id(2*i-1,j),y=id(2*i-2,j); add(x,y,wi,wi); } for(int i=1;i<n;i++) for(int j=1;j<=m;j++) { int wi,x,y;cin>>wi; if(j==1)x=T,y=id(2*i,j); else if(j==m)x=S,y=id(2*i-1,j-1); else x=id(2*i-1,j-1),y=id(2*i,j); add(x,y,wi,wi); } for(int i=1;i<n;i++) for(int j=1;j<m;j++) { int wi;cin>>wi; int x=id(2*i,j),y=id(2*i-1,j); add(x,y,wi,wi); } cout<<dij(); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现