数组开的差不多大,为什么第一个不RE,第二个就RE?太诡异了
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,a,b,c,w[1100][1100];
int lin[1000010],tot,v[1000010];
long long d[3][1000010];
struct edge{
int to,w,next;
}ed[50000010];
struct node{
int v,step;
bool operator < (const node x)const{
return step>x.step;
}
};
priority_queue<node> q;
void add(int x,int y,int w)
{
ed[tot].to=y;
ed[tot].w=w;
ed[tot].next=lin[x];
lin[x]=tot++;
}
void dic(int s,int o)
{
memset(v,0,sizeof(v));
memset(d[o],0x29,sizeof(d[o]));
d[o][s]=0;
q.push((node){s,0});
while(!q.empty())
{
node cur=q.top();
q.pop();
int t=cur.v;
if(v[t]==0)
{
v[t]=1;
for(int i=lin[t];i!=-1;i=ed[i].next)
{
if(v[ed[i].to]==0&&d[o][ed[i].to]>d[o][t]+ed[i].w)
{
d[o][ed[i].to]=d[o][t]+ed[i].w;
q.push((node){ed[i].to,d[o][ed[i].to]});
}
}
}
}
}
int main()
{
memset(lin,-1,sizeof(lin));
scanf("%d%d%d%d%d",&n,&m,&a,&b,&c);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&w[i][j]);
}
}
int st=a,z1=(m*(n-1)+b),z2=(m*(n-1)+c);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int d1,d2=-1,d3=-1;
d1=(i-1)*m+j;
if(j!=m)
d2=(i-1)*m+j+1;
if(i!=n)
d3=i*m+j;
if(d2!=-1)
{
add(d1,d2,w[i][j+1]);
add(d2,d1,w[i][j]);
}
if(d3!=-1)
{
add(d1,d3,w[i+1][j]);
add(d3,d1,w[i][j]);
}
}
}
dic(st,0);
dic(z1,1);
dic(z2,2);
long long ans=3000457347618258600;
int jd;
for(int i=1;i<=n*m;i++)
{
int xx=i/m+1,yy=i-(xx-1)*m;
if(ans>d[0][i]+d[1][i]+d[2][i]-w[xx][yy]*2ll+w[1][a]+w[n][b]+w[n][c])
{
ans=d[0][i]+d[1][i]+d[2][i]-w[xx][yy]*2ll+w[1][a]+w[n][b]+w[n][c];
jd=i;
}
}
printf("%d\n",ans);
return 0;
}
//建图
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const long long INF=3e18;
struct node{
int nxt,to,w;
}edge[7000010];
int temp[1010];
int head[1010];
int n,m,a,b,c,op,idx,num;
int vis[1010];
int w[1010][1010];
int star1[4],star2[4];
LL dis[1010][3];
LL ans=2*INF,id;
void add(int u,int v,int w)
{
edge[++idx].nxt=head[u];
edge[idx].to=v;
edge[idx].w=w;
head[u]=idx;
}
priority_queue<pair<LL,int> > q;
void dijkstra(int s,int cnt)//cnt=1时存的是闪电的单源最短路,
{
for(int i=1;i<=n*m;i++)//初始化
{
vis[i]=0;
}
q.push(make_pair(0,s));
++op;
dis[s][cnt]=w[star1[op]][star2[op]];
while(q.size())
{
int x=q.top().second;
q.pop();
if(vis[x])
continue;
vis[x]=1;
for(int i=head[x];i;i=edge[i].nxt)
{
int y=edge[i].to;
if(dis[x][cnt]+edge[i].w<dis[y][cnt])
{
dis[y][cnt]=dis[x][cnt]+edge[i].w;
q.push(make_pair(-dis[y][cnt],y));
}
}
}
}
int main()
{
cin>>n>>m>>a>>b>>c;
star1[1]=n,star1[2]=1,star1[3]=1;
star2[1]=a,star2[2]=b,star2[3]=c;
for(int i=n;i>=1;i--)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&w[i][j]);
temp[++id]=w[i][j];
}
}
int i=n,j=1;
num=1;
while(1)//先存横向边
{
if(j>=m)//j==m时,j+1溢出,换到下一行
{
if(i==1)//已经是最后一行了
break;
i--;
j=1;
num++;//5到6之间没边
}
add(num,num+1,w[i][j+1]);//1->2 w=8
add(num+1,num,w[i][j]);//2->1 w=1
j++;
num++;
}
i=n,j=1,num=1;
while(1)//再存竖向边
{
if(j>m)
{
if(i==2)
break;
i--;
j=1;
}
add(num,num+m,w[i-1][j]);//i=5,j=1,,i=4,j=1
add(num+m,num,w[i][j]);//i=5,j=1
j++;
num++;
}
int st1=a,st2=(n-1)*m+b,st3=(n-1)*m+c;//算出起点坐标对应点的编号
for(int i=1;i<=n*m;i++)//总点数
{
for(int j=1;j<=3;j++)
{
dis[i][j]=INF;
}
}
dijkstra(st1,0);
dijkstra(st2,1);
dijkstra(st3,2);
for(int i=1;i<=n*m;i++)
{
ans=min(ans,dis[i][0]+dis[i][1]+dis[i][2]-2*temp[i]);
}
cout<<ans;
return 0;
}