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

题目描述

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;
}


猜你喜欢

转载自blog.csdn.net/zhouhongkai06/article/details/80720346
今日推荐