思路
将面看成点,然后将边转换成面和面之间的边,然后跑一遍最短路,就可以了。
但是具体那个是起点,那个是终点,是这么进行确定的,我还不太确定。
代码
#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;
}
标签:int,wi,else,兔子,now,id,dis
From: https://www.cnblogs.com/basicecho/p/16992853.html