問題 D: 貨物運輸 (good)------------------------------思維(多源BFS)

題目描述
隨着新鐵路線的貫通,夏之國的商貿日益繁榮。看着一輛輛滿載貨物的列車駛入車站,前來搬運貨物的工人們排成了長龍。在這炎炎烈日下,他們被僱傭着,要搬運貨物到指定的位置。

如下圖所示,夏之國所在區域可以看成是一個n×n的方格圖,方格的格點上的位置上可能包含火車站(藍色標註)或商店(綠色標註),有一些格點是不能經過的(紅色標註)。方格圖中的線表示可以行走的道路,相鄰兩個格點的距離爲1。貨物運輸必須走可以行走的道路,而且不能經過紅色標註的點。
在這裏插入圖片描述

夏之國共有k座火車站,現在每座火車站都進了若干單位的貨物,這些貨物要從火車站運往商店銷售。夏之國一共有m家商店,由於商店是連鎖的,因此每個貨物都可以運往任意一個商店。每個商店可以接受任意多的貨物。

運輸的主要成本體現在路上所行走的距離。由於貨物過於龐大,每名工人只能運送一件貨物。現有足量工人在各個火車站等候,請你爲每名工人分配貨物運送的目的地,使得它們行走的距離和最小。
輸入
輸入的第一行包含四個整數n,m,k,d,分別表示方格圖的大小、商店數量、火車站數量,以及不能經過的點的數量。
接下來m行,每行兩個整數xi,yi,表示每個商店在方格圖中的橫座標和縱座標。
接下來k行,每行三個整數xi,yi,ci,分別表示每個火車站在方格圖中的橫座標、縱座標和貨物的量。(注意,由於夏之國充分利用了空中和地下空間,因此可能有多個火車站在方格圖中的同一個位置。)
接下來d行,每行兩個整數xi,yi,分別表示每個不能經過的點的橫座標和縱座標。
輸出
輸出一個整數,表示最優方案下工人運輸行走的距離和。
樣例輸入 Copy
10 2 3 3
1 1
8 8
1 5 1
2 3 3
6 7 2
1 2
2 2
6 8
樣例輸出 Copy
29
提示
在這裏插入圖片描述

解析:
多源BFS ,我們依次把商店加入到隊列中,可以求出各商店到每個車站的最短距離,最後累加去求解即可。

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int N=1009;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
ll dist[N][N];
bool vis[N][N];
int n,m,k,d;
ll w[N*N];
struct node
{
	int x,y;
 } shop[N*N],ston[N*N];
int main()
{
	memset(dist,0x3f,sizeof dist);
	queue<PII> q;
	scanf("%d %d %d %d",&n,&m,&k,&d);
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d",&shop[i].x,&shop[i].y);
		dist[shop[i].x][shop[i].y]=0;
		q.push({shop[i].x,shop[i].y});
	}
	for(int i=1;i<=k;i++)
	{
		scanf("%d %d",&ston[i].x,&ston[i].y);
		scanf("%lld",&w[i]);
	}
	for(int i=1,x,y;i<=d;i++)
	{
		scanf("%d %d",&x,&y);
		vis[x][y]=1;
	}
	
	while(q.size())
	{
		
		auto t= q.front();q.pop();
		for(int i=0;i<4;i++)
		{
			int x=dx[i]+t.first;
			int y=dy[i]+t.second;
			if(x<1||x>n||y<1||y>n||vis[x][y]) continue;
			if(dist[t.first][t.second]+1>=dist[x][y]) continue;
			dist[x][y]=dist[t.first][t.second]+1LL;
			q.push({x,y});
			//vis[t.first][t.second]=1;
		}
	
	}
	ll ans=0;
	for(int i=1;i<=k;i++) 
	{
	//	cout<<w[i]<<"  "<<dist[ston[i].x][ston[i].y]<<endl;;
		ans=(ans+w[i]*dist[ston[i].x][ston[i].y]);
	}
	printf("%lld\n",ans);
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章