洛谷 P3106 [USACO14OPEN]GPS的决斗Dueling GPS's

题目描述

Farmer John has recently purchased a new car online, but in his haste heaccidentally clicked the "Submit" button twice when selecting extrafeatures for the car, and as a result the car ended up equipped with twoGPS navigation systems! Even worse, the two systems often make conflictingdecisions about the route that FJ should take.The map of the region in which FJ lives consists of N intersections(2 <= N <= 10,000) and M directional roads (1 <= M <= 50,000). Road iconnects intersections A_i (1 <= A_i <= N) and B_i (1 <= B_i <= N). Multiple roads could connect the same pair of intersections, and abi-directional road (one permitting two-way travel) is represented by twoseparate directional roads in opposite orientations. FJ's house is locatedat intersection 1, and his farm is located at intersection N. It ispossible to reach the farm from his house by traveling along a series ofdirectional roads.Both GPS units are using the same underlying map as described above;however, they have different notions for the travel time along each road. Road i takes P_i units of time to traverse according to the first GPS unit,and Q_i units of time to traverse according to the second unit (eachtravel time is an integer in the range 1..100,000).FJ wants to travel from his house to the farm. However, each GPS unitcomplains loudly any time FJ follows a road (say, from intersection X tointersection Y) that the GPS unit believes not to be part of a shortestroute from X to the farm (it is even possible that both GPS units cancomplain, if FJ takes a road that neither unit likes). Please help FJ determine the minimum possible number of total complaints hecan receive if he chooses his route appropriately. If both GPS unitscomplain when FJ follows a road, this counts as +2 towards the total.
 

输入

* Line 1: The integers N and M.Line i describes road i with four integers: A_i B_i P_i Q_i.
 

输出

* Line 1: The minimum total number of complaints FJ can receive if he routes himself from his house to the farm optimally.
 

样例输入 

5 7
3 4 7 1
1 3 2 20
1 4 17 18
4 5 25 3
1 2 10 1
3 5 4 14
2 4 6 5

样例输出 

1

提示:

INPUT DETAILS:There are 5 intersections and 7 directional roads. The first road connectsfrom intersection 3 to intersection 4; the first GPS thinks this road takes7 units of time to traverse, and the second GPS thinks it takes 1 unit oftime, etc.

OUTPUT DETAILS:If FJ follows the path 1 -> 2 -> 4 -> 5, then the first GPS complains onthe 1 -> 2 road (it would prefer the 1 -> 3 road instead). However, forthe rest of the route 2 -> 4 -> 5, both GPSs are happy, since this is ashortest route from 2 to 5 according to each GPS.


来源USACO 2014 Open Silver

题解:首先,我们要求出n号点到各个点的在导航仪1和导航仪2下的最短距离,同时记录下当前这个点再走哪条边才为最短距离中的一边.然后,我们从1号点开始搜,警告=5,判断当前该边若为导航仪1的最短路,则警告--,当前该边若为导航仪2的最短路,则警告--,作为当前该点到边的另一边的点的权值。若能使下个点的警告数减少,则更新。最后输出n号点的最少警告数即可。( 代码有点长,请不要介意
#include <cstdio>
#include <cstring>
#define N 50005
#define M 10005
int n,m,x,y,z1,z2,cnt,head,tail,top,top1;
int first[N],next[N],v[N],w[N];
int first1[N],next1[N],v1[N],w1[N];
int first2[N],next2[N],v2[N];
int dis[M],dis1[M],dis2[M],f[M],f1[M];
int q[M*10];
bool vis[M];
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)
{
	memset(dis,0x3f3f3f3f,sizeof(dis));
	dis[x]=0;
	head=0;
	tail=1;
	vis[x]=1;
	q[1]=x;
	while (head<tail)
	{
		head++;
		vis[q[head]]=0;
		for (int i=first[q[head]];i;i=next[i])
		{
			int k=v[i];
			if (dis[k]>dis[q[head]]+w[i])
			{
				dis[k]=dis[q[head]]+w[i];
				f[k]=i;
				if (!vis[k])
				{
					tail++;
					q[tail]=k;
					vis[k]=1;
				}
			}
		}
	}
}
inline void spfa1(int x)
{
	memset(dis1,0x3f3f3f3f,sizeof(dis1));
	memset(vis,0,sizeof(vis));
	dis1[x]=0;
	head=0;
	tail=1;
	vis[x]=1;
	q[1]=x;
	while (head<tail)
	{
		head++;
		vis[q[head]]=0;
		for (int i=first1[q[head]];i;i=next1[i])
		{
			int k=v1[i];
			if (dis1[k]>dis1[q[head]]+w1[i])
			{
				dis1[k]=dis1[q[head]]+w1[i];
				f1[k]=i;
				if (!vis[k])
				{
					tail++;
					q[tail]=k;
					vis[k]=1;
				}
			}
		}
	}
}
inline void spfa2(int x)
{
	memset(dis2,0x3f3f3f3f,sizeof(dis2));
	memset(vis,0,sizeof(vis));
	dis2[x]=0;
	head=0;
	tail=1;
	vis[x]=1;
	q[1]=x;
	while (head<tail)
	{
		head++;
		vis[q[head]]=0;
		for (int i=first2[q[head]];i;i=next2[i])
		{
			int k=v2[i],ww=2;
			if (i==f[q[head]]) ww--;
			if (i==f1[q[head]]) ww--;
			if (dis2[k]>dis2[q[head]]+ww)
			{
				dis2[k]=dis2[q[head]]+ww;
				if (!vis[k])
				{
					tail++;
					q[tail]=k;
					vis[k]=1;
				}
			}
		}
	}
}
int main()
{
	n=read(),m=read();
	for (int i=1;i<=m;i++)
	{
		x=read(),y=read(),z1=read(),z2=read();
		next[++cnt]=first[y];
		first[y]=cnt;
		v[cnt]=x;
		w[cnt]=z1;
		next1[cnt]=first1[y];
		first1[y]=cnt;
		v1[cnt]=x;
		w1[cnt]=z2;
		next2[cnt]=first2[x];
		first2[x]=cnt;
		v2[cnt]=y;
	}
	spfa(n);
	spfa1(n);
	spfa2(1);
	printf("%d\n",dis2[n]);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值