关于月赛第二题
  • 板块学术版
  • 楼主mot1ve
  • 当前回复7
  • 已保存回复7
  • 发布时间2020/9/19 22:15
  • 上次更新2023/11/5 12:56:27
查看原帖
关于月赛第二题
250699
mot1ve楼主2020/9/19 22:15

数组开的差不多大,为什么第一个不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;
} 
2020/9/19 22:15
加载中...