# bzoj3538 [Usaco2014 Open]Dueling GPS

## 3538: [Usaco2014 Open]Dueling GPS

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 240  Solved: 145
[Submit][Status][Discuss]

## Input

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

## Output

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

## Sample Input

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

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

## Sample Output

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

## Source

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>

using namespace std;

const int maxn = 10010,maxm = 50010,inf = 0x7ffffff;

int n,m,vis[maxn],d1[maxn],d2[maxn];
int head1[maxn],to1[maxm],nextt1[maxm],tot1 = 1,w1[maxm],w2[maxm];
int head[maxn],to[maxm],nextt[maxm],tot = 1,w[maxm],d3[maxn];

void add1(int x,int y,int z,int z2)
{
w1[tot1] = z;
w2[tot1] = z2;
to1[tot1] = y;
}

void add(int x,int y,int z)
{
w[tot] = z;
to[tot] = y;
}

void spfa1()
{
memset(vis,0,sizeof(vis));
for (int i = 1; i <= n; i++)
d1[i] = inf;
queue <int> q;
q.push(n);
vis[n] = 1;
d1[n] = 0;
while (!q.empty())
{
int u = q.front();
q.pop();
vis[u] = 0;
for (int i = head1[u];i;i = nextt1[i])
{
int v = to1[i];
if (d1[v] > d1[u] + w1[i])
{
d1[v] = d1[u] + w1[i];
if (!vis[v])
{
vis[v] = 1;
q.push(v);
}
}
}
}
}

void spfa2()
{
memset(vis,0,sizeof(vis));
for (int i = 1; i <= n; i++)
d2[i] = inf;
queue <int> q;
q.push(n);
vis[n] = 1;
d2[n] = 0;
while (!q.empty())
{
int u = q.front();
q.pop();
vis[u] = 0;
for (int i = head1[u];i;i = nextt1[i])
{
int v = to1[i];
if (d2[v] > d2[u] + w2[i])
{
d2[v] = d2[u] + w2[i];
if (!vis[v])
{
vis[v] = 1;
q.push(v);
}
}
}
}
}

void spfa3()
{
memset(vis,0,sizeof(vis));
for (int i = 1; i <= n; i++)
d3[i] = inf;
queue <int> q;
q.push(1);
vis = 1;
d3 = 0;
while (!q.empty())
{
int u = q.front();
q.pop();
vis[u] = 0;
for (int i = head[u];i;i = nextt[i])
{
int v = to[i];
if (d3[v] > d3[u] + w[i])
{
d3[v] = d3[u] + w[i];
if (!vis[v])
{
vis[v] = 1;
q.push(v);
}
}
}
}
}

int main()
{
scanf("%d%d",&n,&m);
for (int i = 1; i <= m; i++)
{
int u,v,p,q;
scanf("%d%d%d%d",&u,&v,&p,&q);
}
spfa1();
spfa2();
for (int i = 1; i <= n; i++)
for (int j = head1[i];j;j = nextt1[j])
{
int v = to1[j],t = 0;
if (d1[v] != d1[i] + w1[j]) //判断在不在最短路上
t++;
if (d2[v] != d2[i] + w2[j])
t++;
//printf("%d %d %d\n",v,i,t);
}