货物运输 (good)
题目描述
随着新铁路线的贯通,夏之国的商贸日益繁荣。看着一辆辆满载货物的列车驶入车站,前来搬运货物的工人们排成了长龙。在这炎炎烈日下,他们被雇佣着,要搬运货物到指定的位置。
如下图所示,夏之国所在区域可以看成是一个n×n的方格图,方格的格点上的位置上可能包含火车站(蓝色标注)或商店(绿色标注),有一些格点是不能经过的(红色标注)。方格图中的线表示可以行走的道路,相邻两个格点的距离为1。货物运输必须走可以行走的道路,而且不能经过红色标注的点。
夏之国共有k座火车站,现在每座火车站都进了若干单位的货物,这些货物要从火车站运往商店销售。夏之国一共有m家商店,由于商店是连锁的,因此每个货物都可以运往任意一个商店。每个商店可以接受任意多的货物。
运输的主要成本体现在路上所行走的距离。由于货物过于庞大,每名工人只能运送一件货物。现有足量工人在各个火车站等候,请你为每名工人分配货物运送的目的地,使得它们行走的距离和最小。
如下图所示,夏之国所在区域可以看成是一个n×n的方格图,方格的格点上的位置上可能包含火车站(蓝色标注)或商店(绿色标注),有一些格点是不能经过的(红色标注)。方格图中的线表示可以行走的道路,相邻两个格点的距离为1。货物运输必须走可以行走的道路,而且不能经过红色标注的点。
夏之国共有k座火车站,现在每座火车站都进了若干单位的货物,这些货物要从火车站运往商店销售。夏之国一共有m家商店,由于商店是连锁的,因此每个货物都可以运往任意一个商店。每个商店可以接受任意多的货物。
运输的主要成本体现在路上所行走的距离。由于货物过于庞大,每名工人只能运送一件货物。现有足量工人在各个火车站等候,请你为每名工人分配货物运送的目的地,使得它们行走的距离和最小。
输入
输入的第一行包含四个整数n,m,k,d,分别表示方格图的大小、商店数量、火车站数量,以及不能经过的点的数量。
接下来m行,每行两个整数xi,yi,表示每个商店在方格图中的横坐标和纵坐标。
接下来k行,每行三个整数xi,yi,ci,分别表示每个火车站在方格图中的横坐标、纵坐标和货物的量。(注意,由于夏之国充分利用了空中和地下空间,因此可能有多个火车站在方格图中的同一个位置。)
接下来d行,每行两个整数xi,yi,分别表示每个不能经过的点的横坐标和纵坐标。
接下来m行,每行两个整数xi,yi,表示每个商店在方格图中的横坐标和纵坐标。
接下来k行,每行三个整数xi,yi,ci,分别表示每个火车站在方格图中的横坐标、纵坐标和货物的量。(注意,由于夏之国充分利用了空中和地下空间,因此可能有多个火车站在方格图中的同一个位置。)
接下来d行,每行两个整数xi,yi,分别表示每个不能经过的点的横坐标和纵坐标。
输出
输出一个整数,表示最优方案下工人运输行走的距离和。
提示
题解
多个源点的bfs,把每一个商店当作源点放入队列进行bfs就可以了。
1 #include <stack> 2 #include <queue> 3 #include <cmath> 4 #include <vector> 5 #include <cstdio> 6 #include <cstring> 7 #include <iostream> 8 #include <algorithm> 9 #define fi first 10 #define se second 11 #define IL inline 12 #define RG register 13 #define MP(a,b) make_pair(a,b) 14 #define PI acos(-1) 15 #define Mod 998244353 16 using namespace std; 17 typedef long long LL; 18 typedef unsigned long long ULL; 19 typedef double DB; 20 typedef pair<int, int> PR; 21 const int N = 1009; 22 const int M = 126750; 23 int gx[] = {0, 0, 1, -1}; 24 int gy[] = {1, -1, 0, 0}; 25 int n, m, k, d; 26 LL f[N][N], w[N*N], ans; 27 bool v[N][N]; 28 vector<PR> shop, station; 29 queue<PR> q; 30 IL int read() 31 { 32 int num = 0; bool flag = 0; char c; 33 while((c=getchar())==' ' || c=='\n' || c=='\r'); 34 if(c == '-') flag = 1; else num = c - '0'; 35 while(isdigit(c=getchar())) 36 num = num * 10 + c - '0'; 37 return flag ? -num : num; 38 } 39 IL int mabs(int x) 40 { 41 return x < 0 ? -x : x; 42 } 43 44 int main(void) 45 { 46 n = read(); m = read(); k = read(); d = read(); 47 memset(f, 0x3f, sizeof(f)); 48 shop.resize(m); 49 station.resize(k); 50 for(int i = 0; i < m; i++) 51 { 52 shop[i].fi = read(); 53 shop[i].se = read(); 54 f[shop[i].fi][shop[i].se] = 0; 55 q.push(shop[i]); 56 } 57 for(int i = 0; i < k; i++) 58 { 59 station[i].fi = read(); 60 station[i].se = read(); 61 w[i] = read(); 62 } 63 for(int i = 0; i < d; i++) 64 { 65 int x = read(), y = read(); 66 v[x][y] = 1; 67 } 68 while(!q.empty()) 69 { 70 PR now = q.front(); 71 q.pop(); 72 for(int i = 0; i < 4; i++) 73 { 74 int x = now.fi + gx[i]; 75 int y = now.se + gy[i]; 76 if(x < 1 || x > n || y < 1 || y > n) continue; 77 if(v[x][y]) continue; 78 if(f[now.fi][now.se]+1>=f[x][y]) continue; 79 f[x][y] = f[now.fi][now.se] + 1LL; 80 q.push(MP(x, y)); 81 } 82 } 83 for(int i = 0; i < k; i++) 84 ans += w[i] * f[station[i].fi][station[i].se]; 85 printf("%lld\n", ans); 86 return 0; 87 }