Luogu3003 [USACO10DEC]苹果交货Apple Delivery

题目描述

贝西有两个又香又脆的红苹果要送给她的两个朋友。当然她可以走的C(1<=C<=200000)条“牛路”都被包含在一种常用的图中,包含了P(1<=P<=100000)个牧场,分别被标为1..P。没有“牛路”会从一个牧场又走回它自己。“牛路”是双向的,每条牛路都会被标上一个距离。最重要的是,每个牧场都可以通向另一个牧场。每条牛路都连接着两个不同的牧场P1_i和P2_i(1<=P1_i,p2_i<=P),距离为D_i。所有“牛路”的距离之和不大于2000000000。

现在,贝西要从牧场PB开始给PA_1和PA_2牧场各送一个苹果(PA_1和PA_2顺序可以调换),那么最短的距离是多少呢?当然,PB、PA_1和PA_2各不相同。

输入格式:

* Line 1: Line 1 contains five space-separated integers: C, P, PB, PA1, and PA2

* Lines 2..C+1: Line i+1 describes cowpath i by naming two pastures it connects and the distance between them: P1_i, P2_i, D_i

输出格式:

* Line 1: The shortest distance Bessie must travel to deliver both apples

路线有两种,一是从PB到PA1再到PA2,二是先到PA2再到PA1。

因为这张图是无向图,所以PA1到PA2和PA2到PA1的距离是一样的,故我们只需要求出从PB出发的最短路,然后比较PB到PA1和PA2的距离即可。

然后以PA1或PA2为起点,求出PA1到PA2的最短路。

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define maxn 100010
#define maxm 500010
using namespace std;
int dis1[maxn],dis2[maxn],head[maxn],cnt,n,m;
bool vis[maxn];
struct edge
{
	int next;
	int to;
	int val;
}e[maxm];
void insert(int u,int v,int w)
{
	e[++cnt].next=head[u];
	head[u]=cnt;
	e[cnt].to=v;
	e[cnt].val=w;
}
void dijkstra1(int s)
{
	memset(vis,false,sizeof(vis));
	memset(dis1,0x3f,sizeof(dis1));
	priority_queue<pair<int,int> > q;
	dis1[s]=0;
	q.push(make_pair(0,s));
	while(!q.empty()){
		int now=q.top().second;
		q.pop();
		if(vis[now]) continue;
		vis[now]=true;
		for(int i=head[now];i;i=e[i].next){
			int v=e[i].to;
			if(dis1[v]>dis1[now]+e[i].val){
				dis1[v]=dis1[now]+e[i].val;
				q.push(make_pair(-dis1[v],v));
			}
		}
	}
}
void dijkstra2(int s)
{
	memset(vis,false,sizeof(vis));
	memset(dis2,0x3f,sizeof(dis2));
	priority_queue<pair<int,int> > q;
	dis2[s]=0;
	q.push(make_pair(0,s));
	while(!q.empty()){
		int now=q.top().second;
		q.pop();
		if(vis[now]) continue;
		vis[now]=true;
		for(int i=head[now];i;i=e[i].next){
			int v=e[i].to;
			if(dis2[v]>dis2[now]+e[i].val){
				dis2[v]=dis2[now]+e[i].val;
				q.push(make_pair(-dis2[v],v));
			}
		}
	}
}
int main()
{
	int s,t1,t2;
	cin>>m>>n>>s>>t1>>t2;
	for(int i=1;i<=m;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		insert(x,y,z);
		insert(y,x,z);
	}
	dijkstra1(s);
	dijkstra2(t1);
	cout<<min(dis1[t1],dis1[t2])+dis2[t2];
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42318710/article/details/82501351