代码:
#include <cstdio>
#include <cstring>
#define MXV 2000005
#define MXE 6004005
int val[MXE],next[MXE],to[MXE];
int head[MXV],size,n,m,ep; //ep = end point
bool out[MXV];
int dis[MXV],ans=0;
struct hpnode{
int num,val;
};
class minheap{
public:
hpnode H[MXV];
int sz,pos[MXV];
minheap(){
for(int i=0;i<MXV;i++)
H[i].num=0,H[i].val=0x7fffffff;
H[0].val=0;
memset(pos,0,sizeof(pos));
sz=0;
}
void swap(int x,int y){
hpnode t=H[x]; int tp=pos[x];
pos[H[x].num]=pos[H[y].num]; pos[H[y].num]=tp;
H[x]=H[y]; H[y]=t;
}
void fixu(int p){
while(H[p].val<H[p>>1].val){
swap(p,p>>1);
p>>=1;
}
}
void fixd(int p){
while(1){
int t=(H[p<<1].val<H[p].val&&(p<<1<=sz))?p<<1:p;
t=(H[(p<<1)+1].val<H[t].val&&((p<<1)+1<=sz))?(p<<1)+1:t;
if(t==p)return;
swap(p,t); p=t;
}
}
void insert(int n,int v){
H[++sz].num=n; H[sz].val=v;
pos[n]=sz; fixu(sz);
}
void del(int p){
if(p==sz){sz--;pos[p]=0;return;}
swap(p,sz); sz--; pos[p]=0;
fixu(p); fixd(p);
}
int popmin(){
int t=H[1].num;
del(1); return t;
}
}hp;
int change(int x,int y,int z){return (((x-1)*(m-1)+y)<<1)+z;}
int min(int a,int b){return a<b?a:b;}
void insert(int f,int t,int v){
val[++size]=v; next[size]=head[f]; to[size]=t; head[f]=size;
val[++size]=v; next[size]=head[t]; to[size]=f; head[t]=size;
}
int dijkstra(){
memset(out,0,sizeof(out));
memset(dis,0x7f,sizeof(dis));
//for(int i=0;i<MXV;i++)dis[i]=0x7fffffff; //可设置起点为[0],终点为[n*m*2+2].
out[0]=1; dis[0]=0; hp.insert(0,0);
for(int i=1;i<=n*m*2+2;i++){
int nowp=hp.popmin();
if(nowp==ep)return dis[ep];
int now=head[nowp];
while(val[now]){
if(out[to[now]]){
now=next[now];
continue;
}
dis[to[now]]=min(dis[to[now]],dis[nowp]+val[now]);
if(!hp.pos[to[now]])
hp.insert(to[now],dis[to[now]]);
else{
hp.H[hp.pos[to[now]]].val=dis[to[now]];
hp.fixu(hp.pos[to[now]]);
}
now=next[now];
}
out[nowp]=1;
}
return dis[ep];
}
void init(){
scanf("%d%d",&n,&m);
int t; ep=1;
//read_1
for(int i=1;i<m;i++){
scanf("%d",&t);
insert(change(1,i,1),ep,t);
}
for(int i=2;i<n;i++)
for(int j=1;j<m;j++){
scanf("%d",&t);
insert(change(i-1,j,0),change(i,j,1),t);
}
for(int i=1;i<m;i++){
scanf("%d",&t);
insert(change(n-1,i,0),0,t);
}
//read_2
for(int i=1;i<n;i++){
scanf("%d",&t);
insert(change(i,1,0),0,t);
for(int j=2;j<m;j++){
scanf("%d",&t);
insert(change(i,j-1,1),change(i,j,0),t);
}
scanf("%d",&t);
insert(change(i,m-1,1),ep,t);
}
//read_3
for(int i=1;i<n;i++)
for(int j=1;j<m;j++){
scanf("%d",&t);
insert(change(i,j,0),change(i,j,1),t);
}
}
int main(){
init();
printf("%d\n",dijkstra());
return 0;
}
#include <cstdio>
#include <cstring>
#define MXV 2000005
#define MXE 6004005
int val[MXE],next[MXE],to[MXE];
int head[MXV],size,n,m,ep; //ep = end point
bool out[MXV];
int dis[MXV],ans=0;
struct hpnode{
int num,val;
};
class minheap{
public:
hpnode H[MXV];
int sz,pos[MXV];
minheap(){
for(int i=0;i<MXV;i++)
H[i].num=0,H[i].val=0x7fffffff;
H[0].val=0;
memset(pos,0,sizeof(pos));
sz=0;
}
void swap(int x,int y){
hpnode t=H[x]; int tp=pos[x];
pos[H[x].num]=pos[H[y].num]; pos[H[y].num]=tp;
H[x]=H[y]; H[y]=t;
}
void fixu(int p){
while(H[p].val<H[p>>1].val){
swap(p,p>>1);
p>>=1;
}
}
void fixd(int p){
while(1){
int t=(H[p<<1].val<H[p].val&&(p<<1<=sz))?p<<1:p;
t=(H[(p<<1)+1].val<H[t].val&&((p<<1)+1<=sz))?(p<<1)+1:t;
if(t==p)return;
swap(p,t); p=t;
}
}
void insert(int n,int v){
H[++sz].num=n; H[sz].val=v;
pos[n]=sz; fixu(sz);
}
void del(int p){
if(p==sz){sz--;pos[p]=0;return;}
swap(p,sz); sz--; pos[p]=0;
fixu(p); fixd(p);
}
int popmin(){
int t=H[1].num;
del(1); return t;
}
}hp;
int change(int x,int y,int z){return (((x-1)*(m-1)+y)<<1)+z;}
int min(int a,int b){return a<b?a:b;}
void insert(int f,int t,int v){
val[++size]=v; next[size]=head[f]; to[size]=t; head[f]=size;
val[++size]=v; next[size]=head[t]; to[size]=f; head[t]=size;
}
int dijkstra(){
memset(out,0,sizeof(out));
memset(dis,0x7f,sizeof(dis));
//for(int i=0;i<MXV;i++)dis[i]=0x7fffffff; //可设置起点为[0],终点为[n*m*2+2].
out[0]=1; dis[0]=0; hp.insert(0,0);
for(int i=1;i<=n*m*2+2;i++){
int nowp=hp.popmin();
if(nowp==ep)return dis[ep];
int now=head[nowp];
while(val[now]){
if(out[to[now]]){
now=next[now];
continue;
}
dis[to[now]]=min(dis[to[now]],dis[nowp]+val[now]);
if(!hp.pos[to[now]])
hp.insert(to[now],dis[to[now]]);
else{
hp.H[hp.pos[to[now]]].val=dis[to[now]];
hp.fixu(hp.pos[to[now]]);
}
now=next[now];
}
out[nowp]=1;
}
return dis[ep];
}
void init(){
scanf("%d%d",&n,&m);
int t; ep=1;
//read_1
for(int i=1;i<m;i++){
scanf("%d",&t);
insert(change(1,i,1),ep,t);
}
for(int i=2;i<n;i++)
for(int j=1;j<m;j++){
scanf("%d",&t);
insert(change(i-1,j,0),change(i,j,1),t);
}
for(int i=1;i<m;i++){
scanf("%d",&t);
insert(change(n-1,i,0),0,t);
}
//read_2
for(int i=1;i<n;i++){
scanf("%d",&t);
insert(change(i,1,0),0,t);
for(int j=2;j<m;j++){
scanf("%d",&t);
insert(change(i,j-1,1),change(i,j,0),t);
}
scanf("%d",&t);
insert(change(i,m-1,1),ep,t);
}
//read_3
for(int i=1;i<n;i++)
for(int j=1;j<m;j++){
scanf("%d",&t);
insert(change(i,j,0),change(i,j,1),t);
}
}
int main(){
init();
printf("%d\n",dijkstra());
return 0;
}