求助
  • 板块P6833 [Cnoi2020] 雷雨
  • 楼主WsW_花逝爆零人
  • 当前回复3
  • 已保存回复3
  • 发布时间2023/8/14 21:32
  • 上次更新2023/11/3 03:45:48
查看原帖
求助
349824
WsW_花逝爆零人楼主2023/8/14 21:32

dijkstra过不了样例。

#include<bits/stdc++.h>
#define ll long long
using namespace std;

struct node{
	int to,w;
	int next;
}edg[4000000];
int elen;

struct point{
	ll ans;
	int x;
	bool operator < (const point &A)const{
		return ans>A.ans;
	}
};

int n,m,a,b,c;

ll fans=1e18;
bool vis[1000003];
int head[1000003];
ll ans[3][1000003]; 
ll Map[1003][1003];

int turn(int x,int y){//二维变一维 
	return m*(x-1)+y;
}

void add(int fr,int to,int w){
	elen++;
	edg[elen].w=w;
	edg[elen].to=to;
	edg[elen].next=head[fr];
	head[fr]=elen;
}

priority_queue<point> q;

void dij(int tt,int i,int j){
	int s=turn(i,j);
	for(int i=1;i<=n*m+1;i++){
		vis[i]=0;
		ans[tt][i]=1e18;
	}
	ans[tt][s]=Map[i][j];
//	vis[s]=1;
	q.push({Map[i][j],s});
	while(!q.empty()){
		int x=q.top().x;
		q.pop();
		if(vis[x])continue;
		vis[x]=1;
		for(int i=head[x];i;i=edg[i].next){
			int to=edg[i].to;
			ll cost=edg[i].w;
			if(ans[tt][to]>ans[tt][x]+cost){
				ans[tt][to]=ans[tt][x]+cost;
				q.push({ans[tt][to],to});
			}
		}
	}
}

int main(){
	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("%lld",&Map[i][j]);
			if(i>1){//连边 
				add(turn(i,j),turn(i-1,j),Map[i][j]);
				add(turn(i-1,j),turn(i,j),Map[i][j]);
			}
			if(j>1){
				add(turn(i,j),turn(i,j-1),Map[i][j]);
				add(turn(i,j-1),turn(i,j),Map[i][j]);
			}
		}
	}
	dij(0,1,a);//三个点分别跑最短路 
	dij(1,n,b);
	dij(2,n,c);
	puts("");
	for(int i=1;i<=n;i++){//枚举分叉点 
		for(int j=1;j<=m;j++){
			cout<<ans[0][turn(i,j)]<<" ";
		}
		puts("");
	}
		puts("");
	for(int i=1;i<=n;i++){//枚举分叉点 
		for(int j=1;j<=m;j++){
			cout<<ans[1][turn(i,j)]<<" ";
		}
		puts("");
	}
		puts("");
	for(int i=1;i<=n;i++){//枚举分叉点 
		for(int j=1;j<=m;j++){
			cout<<ans[2][turn(i,j)]<<" ";
		}
		puts("");
	}
		puts("");
	for(int i=1;i<=n;i++){//枚举分叉点 
		for(int j=1;j<=m;j++){
			cout<<ans[0][turn(i,j)]+ans[1][turn(i,j)]+ans[2][turn(i,j)]-Map[i][j]*2<<" ";
			fans=min(fans,ans[0][turn(i,j)]+ans[1][turn(i,j)]+ans[2][turn(i,j)]-Map[i][j]*2);
		}
		puts("");
	}
	printf("%lld",fans);
	return 0;
} 
2023/8/14 21:32
加载中...