货物运输 (good)

货物运输 (good)

时间限制: 1 Sec  内存限制: 1024 MB

题目描述

随着新铁路线的贯通,夏之国的商贸日益繁荣。看着一辆辆满载货物的列车驶入车站,前来搬运货物的工人们排成了长龙。在这炎炎烈日下,他们被雇佣着,要搬运货物到指定的位置。

如下图所示,夏之国所在区域可以看成是一个n×n的方格图,方格的格点上的位置上可能包含火车站(蓝色标注)或商店(绿色标注),有一些格点是不能经过的(红色标注)。方格图中的线表示可以行走的道路,相邻两个格点的距离为1。货物运输必须走可以行走的道路,而且不能经过红色标注的点。


夏之国共有k座火车站,现在每座火车站都进了若干单位的货物,这些货物要从火车站运往商店销售。夏之国一共有m家商店,由于商店是连锁的,因此每个货物都可以运往任意一个商店。每个商店可以接受任意多的货物。

运输的主要成本体现在路上所行走的距离。由于货物过于庞大,每名工人只能运送一件货物。现有足量工人在各个火车站等候,请你为每名工人分配货物运送的目的地,使得它们行走的距离和最小。

输入

输入的第一行包含四个整数n,m,k,d,分别表示方格图的大小、商店数量、火车站数量,以及不能经过的点的数量。
接下来m行,每行两个整数xi,yi,表示每个商店在方格图中的横坐标和纵坐标。
接下来k行,每行三个整数xi,yi,ci,分别表示每个火车站在方格图中的横坐标、纵坐标和货物的量。(注意,由于夏之国充分利用了空中和地下空间,因此可能有多个火车站在方格图中的同一个位置。)
接下来d行,每行两个整数xi,yi,分别表示每个不能经过的点的横坐标和纵坐标。

输出

输出一个整数,表示最优方案下工人运输行走的距离和。

样例输入

10 2 3 3
1 1
8 8
1 5 1
2 3 3
6 7 2
1 2
2 2
6 8

样例输出

29

提示

题解

  多个源点的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 }
View Code

 

posted @ 2020-06-29 20:55  Johnny-English  阅读(352)  评论(0编辑  收藏  举报