堆优化spfa可以通过此题 (
查看原帖
堆优化spfa可以通过此题 (
371409
Dangerise楼主2024/9/29 15:09

Johnson

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

#define int long long
#define inl inline
#define siz(x) ((int)x.size())
#define me(a,v) memset(a,v,sizeof(a))
#define cp(a,b) memcpy(b,a,(assert(sizeof(a)==sizeof(b)),sizeof(a)))
#define L(i,l,r) for(int i=l;i<=r;i++)
#define R(i,l,r) for(int i=r;i>=l;i--)
typedef vector<int> ve;

inl char gc() {
	return getchar();
}

inl void pc(char c) {
	putchar(c);
}

inl int qread() {
	int ans=0;
	char c=gc();
	bool f=0;
	while(c<'0'||c>'9') {
		if(c=='-') {
			f=1;
		}
		c=gc();
	}
	while(c>='0'&&c<='9') {
		ans=ans*10+c-'0';
		c=gc();
	}
	if(f) {
		return -ans;
	} else {
		return ans;
	}
}

constexpr int N=114514*4,inf=LONG_LONG_MAX-10;

struct P {
	int x,y,w;
};

struct E {
	int v,next;
};

struct V {
	int x,y,d;
};

inline bool operator<(const V& x,const V& y) {
	return x.d>y.d;
}

P p[N];

constexpr int dx[4]= {-1,0,1,0},dy[4]= {0,1,0,-1};

int n,m,q;

bool fail=0;
int h[N],sum[N],iq[N],vc[N];
int w[N][4];

inl int id(int x,int y) {
	return (x-1)*m+y-1;
}

int first=0;
inl void spfa() {
	me(h,0x3f);
//	me(iq,0);

	priority_queue<V> q;
	L(i,1,n) {
		L(j,1,m) {
			int sid=id(i,j);
			iq[sid]=1;
			h[sid]=p[sid].w;
			q.push({i,j,h[sid]});
		}
	}

	while(!q.empty()) {
		int x=q.top().x;
		int y=q.top().y;
		q.pop();
		int uid=id(x,y);
		if(!iq[uid]) {
			continue;
		}
		iq[uid]=0;
		L(i,0,3) {
			int nx=x+dx[i],ny=y+dy[i];
			if(nx<=0||nx>n||ny<=0||ny>m) {
				continue;
			}
			int vid=id(nx,ny);
			if(h[uid]+p[vid].w<h[vid]) {
				vc[vid]++;
				if(vc[vid]>n*m+10) {
					fail=1;
					return;
				}
				h[vid]=h[uid]+p[vid].w;
				q.push({nx,ny,h[vid]});
				iq[vid]=1;
			}
		}
	}
	first=1;
}

int dis[N];
inl void dij(int sx,int sy) {
	me(dis,0x3f);
	priority_queue<V> q;
	int sid=id(sx,sy);
	q.push({sx,sy,p[sid].w});
	dis[sid]=p[sid].w;
	while(!q.empty()) {
		int x=q.top().x,y=q.top().y,d=q.top().d;
		q.pop();
		int uid=id(x,y);
		if(d>dis[uid]) {
			continue;
		}
		L(k,0,3) {
			int nx=x+dx[k],ny=y+dy[k];
			if(nx<=0||nx>n||ny<=0||ny>m) {
				continue;
			}
			int vid=id(nx,ny);
			int wuv=w[uid][k];
			if(dis[uid]+wuv<dis[vid]) {
				dis[vid]=dis[uid]+wuv;
				q.push({nx,ny,dis[vid]});
			}
		}
	}
}

signed main() {
	n=qread(),m=qread(),q=qread();
	L(i,1,n) {
		L(j,1,m) {
			int x=i,y=j;
			int v=id(x,y);
			p[v].x=x,p[v].y=y;
			p[v].w=qread();
		}
	}

	L(i,0,n*m-1) {
		sum[i]=-inf;
	}

	spfa();

	if(fail) {
		puts("No");
		return 0;
	}

	L(i,1,n) {
		L(j,1,m) {
			int uid=id(i,j);
			L(k,0,3) {
				int nx=i+dx[k],ny=j+dy[k];
				if(nx<=0||nx>n||ny<=0||ny>m) {
					continue;
				}
				int vid=id(nx,ny);
				w[uid][k]=p[vid].w+h[uid]-h[vid];
			}
		}
	}

	L(i,1,q) {
		int x=qread(),y=qread();
		dij(x,y);
//		L(i,1,n) {
//			L(j,1,m) {
//				printf("i %lld j %lld h %lld\n",i,j,dis[id(i,j)]);
//			}
//		}
		int uid=id(x,y);
		L(j,0,n*m-1) {
			sum[j]=max(sum[j],dis[j]-h[uid]+h[j]);
		}
	}

	int ans=inf;
	L(i,0,n*m-1) {
		ans=min(ans,sum[i]);
		assert(sum[i]!=-inf);
	}
	assert(ans!=inf);
	printf("%lld\n",ans);
	return 0;
}
2024/9/29 15:09
加载中...