luogu P3096 [USACO13DEC]假期计划(黄金)Vacation Planning (gold)

本文介绍了一种算法解决方案,用于计算AirBovinia航空公司的航班路径问题,特别是涉及枢纽机场的最短路径计算。该算法通过SPFA(Shortest Path Faster Algorithm)实现了高效的路径搜索,并最终确定了所有可能的旅行请求及其最低成本。

题目描述

Air Bovinia operates flights connecting the N farms that thecows live on (1 <= N <= 20,000). As with any airline, K of these farmshave been designated as hubs (1 <= K <= 200, K <= N).

Currently, Air Bovinia offers M one-way flights (1 <= M <=20,000), where flight i travels from farm u_i to farm v_i and costs d_i (1<= d_i <= 10,000) dollars. As with any other sensible airline, for eachof these flights, at least one of u_i and v_i is a hub. There is at most onedirect flight between two farms in any given direction, and no flight startsand ends at the same farm.

Bessie is in charge of running the ticketing services for AirBovinia. Unfortunately, while she was away chewing on delicious hay for a fewhours, Q one-way travel requests for the cows' holiday vacations were received(1 <= Q <= 50,000), where the ith request is from farm a_i to farm b_i.

As Bessie is overwhelmed with the task of processing thesetickets, please help her compute whether each ticket request can be fullfilled,and its minimum cost if it can be done.

To reduce the output size, you should only output the total numberof ticket requests that are possible, and the minimum total cost for them. Notethat this number might not fit into a 32-bit integer.

n个点m条有向边,求两两之间的最短路,要求路径上必须经过编号1~k的至少一个点

输入输出格式

输入格式:
* Line 1: The integers N, M, K, and Q.

* Lines 2..M + 1: Line i+1 contains u_i, v_i, and d_i. (1 <=u_i, v_i <= N, u_i != v_i)

* Lines M + 2..M + K + 1: Each of these lines contains the ID ofa single hub (in the range 1..N).

* Lines M + K + 2..M + K + Q + 1: Two numbers per line,indicating a request for a ticket from farm a_i to b_i. (1 <= a_i, b_i <=N, a_i != b_i)

输出格式:
* Line 1: The number of ticket requests that can be fullfilled.

* Line 2: The minimum total cost of fulling the possible ticketrequests

输入输出样例

输入样例#1 

3 3 1 2 
1 2 10 
2 3 10 
2 1 5 
2 
1 3 
3 1 

输出样例#1 

1 
20 

说明

For the first flight, the only feasible route is 1->2->3,costing 20. There are no flights leaving farm 3, so the poor cows are strandedthere.

题解:这道题目首先是单向边,然后从枢纽入手,算出每个枢纽到每个机场的最短距离,若问题的出发点为枢纽,则ans=出发点到终点的最短距离;若不是,则寻找途经点的中的枢纽,算出最短距离,判断ans若<2e8,就让可行单数+1,总费用+=ans,最后输出即可。

#include <cstdio>
#include <cstring>
#define N 20005
int n,m,k,q,cnt,x,y,z,first[N],next[N],v[N],w[N];
int no,head,tail,qq[N*10],a[N],f[205][N],bo[N];
long long sum;
bool vis[N];
using namespace std;
inline int read()  
{  
    int f=1,x=0;  
    char ch=getchar();  
    if (ch=='-')  
    {  
        f=-1;  
        ch=getchar();  
    }  
    while ((ch<'0')||(ch>'9')) ch=getchar();  
    while ((ch>='0')&&(ch<='9'))  
    {  
        x=x*10+ch-48;  
        ch=getchar();  
    }  
    return f*x;  
}
inline void spfa(int x,int y)
{
	head=0;
	tail=1;
	qq[1]=y;
	f[x][y]=0;
	while (head<tail)
	{
		head++;
		vis[qq[head]]=0;//弹出当前点 
		for (int i=first[qq[head]];i;i=next[i])
		  if (f[x][v[i]]>f[x][qq[head]]+w[i])
		  {
		  	f[x][v[i]]=f[x][qq[head]]+w[i];
		  	if (!vis[v[i]]) 
		  	{//加入当前点 
		  		vis[v[i]]=1;
		  		tail++;
		  		qq[tail]=v[i];
		  	}
		  }
	}
}
int main()
{
	n=read(),m=read(),k=read(),q=read();
	for (int i=1;i<=m;i++) 
	{ 
		x=read(),y=read(),z=read();
		next[++cnt]=first[x];
		first[x]=cnt;
		v[cnt]=y;
		w[cnt]=z;
	}
	for (int i=1;i<=k;i++) 
	{
		a[i]=read();
		bo[a[i]]=i;//记录下当前枢纽是哪条边 
	}
	memset(f,63,sizeof(f));//赋大值 
	for (int i=1;i<=k;i++) spfa(i,a[i]);
	for (int i=1;i<=q;i++)
	{
		x=read(),y=read();
		long long ans=1e9;
		if (bo[x]) ans=f[bo[x]][y]; else
		  for (int j=first[x];j;j=next[j])
		    if (w[j]+f[bo[v[j]]][y]<ans)//算最小值 
		      ans=w[j]+f[bo[v[j]]][y];
		if (ans<2e8) no++,sum+=ans;
	}
	printf("%d\n%lld\n",no,sum);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值