门户网站开发费需入无形资产,淘宝做基础销量怎么网站,如何自己做网址,现在哪个公司的网络比较好problem
luogu-P3350
solution
据说#xff0c;网格图最短路用分治是一个人人皆知的套路。对不起我不是人
类比整体二分的算法流程。
考虑在一个 (xl,yl)−(yl,yr)(xl,yl)-(yl,yr)(xl,yl)−(yl,yr) 矩阵内处理 [ql,qr][ql,qr][ql,qr] 的询问。
以矩阵的中界线 mid\text{…problem
luogu-P3350
solution
据说网格图最短路用分治是一个人人皆知的套路。对不起我不是人
类比整体二分的算法流程。
考虑在一个 (xl,yl)−(yl,yr)(xl,yl)-(yl,yr)(xl,yl)−(yl,yr) 矩阵内处理 [ql,qr][ql,qr][ql,qr] 的询问。
以矩阵的中界线 mid\text{mid}mid 将矩阵划成两半显然哪一维更长划哪一维。
以中界线上的每一个点为起点跑一遍最短路然后更新所有需要跨过这条线的询问的答案相当于是强制路线必须经过该点。
如果不需要跨过这条线即询问的起终点均在线的某一侧就分成 l,rl,rl,r 两个部分继续分治下去。
时间复杂度好像都说是 O(NNlogN)O(N\sqrt{N}\log N)O(NNlogN)。
具体见代码即可明白。
code
#include bits/stdc.h
using namespace std;
#define maxn 20005
#define maxq 100005
#define Pair pair int, int
struct node { int u, v, id; }q[maxq], l[maxq], r[maxq];
vector Pair G[maxn];
priority_queue Pair, vector Pair , greater Pair que;
int x[maxn], y[maxn], dis[maxn], ans[maxq];
int n, m, Q;int id( int i, int j ) { return (i - 1) * m j; }void dijkstra( int s, int xl, int xr, int yl, int yr ) {for( int i xl;i xr;i )for( int j yl;j yr;j )dis[id(i, j)] 0x7f7f7f7f;que.push( make_pair( dis[s] 0, s ) );while( ! que.empty() ) {int u que.top().second, w que.top().first;que.pop();if( dis[u] ^ w ) continue;for( int i 0;i G[u].size();i ) {int v G[u][i].first; w G[u][i].second;if( x[v] xl or x[v] xr or y[v] yl or y[v] yr ) continue;if( dis[v] dis[u] w )que.push( make_pair( dis[v] dis[u] w, v ) );}}
}void solve( int ql, int qr, int xl, int xr, int yl, int yr ) {if( ql qr or xl xr or yl yr ) return;int cntl 0, cntr 0;if( xr - xl yr - yl ) {int mid xr xl 1;for( int i yl;i yr;i ) {dijkstra( id(mid, i), xl, xr, yl, yr );for( int j ql;j qr;j )ans[q[j].id] min( ans[q[j].id], dis[q[j].u] dis[q[j].v] );}for( int i ql;i qr;i ) {if( x[q[i].u] mid and x[q[i].v] mid ) l[ cntl] q[i];if( x[q[i].u] mid and x[q[i].v] mid ) r[ cntr] q[i];}for( int i 1;i cntl;i ) q[ql i - 1] l[i];for( int i 1;i cntr;i ) q[ql cntl i - 1] r[i];solve( ql, ql cntl - 1, xl, mid - 1, yl, yr );solve( ql cntl, ql cntl cntr - 1, mid 1, xr, yl, yr );}else {int mid yr yl 1;for( int i xl;i xr;i ) {dijkstra( id(i, mid), xl, xr, yl, yr );for( int j ql;j qr;j )ans[q[j].id] min( ans[q[j].id], dis[q[j].u] dis[q[j].v] );}for( int i ql;i qr;i ) {if( y[q[i].u] mid and y[q[i].v] mid ) l[ cntl] q[i];if( y[q[i].u] mid and y[q[i].v] mid ) r[ cntr] q[i];}for( int i 1;i cntl;i ) q[ql i - 1] l[i];for( int i 1;i cntr;i ) q[ql cntl i - 1] r[i];solve( ql, ql cntl - 1, xl, xr, yl, mid - 1 );solve( ql cntl, ql cntl cntr - 1, xl, xr, mid 1, yr );}
}int main() {scanf( %d %d, n, m );for( int i 1;i n;i )for( int j 1, x;j m;j ) {scanf( %d, x );G[id(i, j)].push_back( make_pair( id(i, j 1), x ) );G[id(i, j 1)].push_back( make_pair( id(i, j), x ) );}for( int i 1;i n;i )for( int j 1, x;j m;j ) {scanf( %d, x );G[id(i, j)].push_back( make_pair( id(i 1, j), x ) );G[id(i 1, j)].push_back( make_pair( id(i, j), x ) );}for( int i 1;i n;i )for( int j 1;j m;j )x[id(i, j)] i, y[id(i, j)] j;scanf( %d, Q );for( int i 1, a1, b1, a2, b2;i Q;i ) {scanf( %d %d %d %d, a1, b1, a2, b2 );q[i] (node){ id(a1, b1), id(a2, b2) }, q[i].id i;}memset( ans, 0x7f, sizeof( ans ) );solve( 1, Q, 1, n, 1, m );for( int i 1;i Q;i ) printf( %d\n, ans[i] );return 0;
}