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

题目描述

给你一个N个点的有向图,可能有重边.

有两个GPS定位系统,分别认为经过边i的时间为Pi,和Qi.

每走一条边的时候,如果一个系统认为走的这条边不是它认为的最短路,就会受到警告一次T T

两个系统是分开警告的,就是说当走的这条边都不在两个系统认为的最短路范围内,就会受到2次警告.

如果边(u,v)不在u到n的最短路径上,这条边就受到一次警告,求从1到n最少受到多少次警告。

输入输出格式

输入格式:

  • 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.

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=50000+5;
inline void read(int &x){
    x=0; char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
}
int n,m,tot,u[maxn],v[maxn],p[maxn],q[maxn];
int head[maxn],dis[4][maxn];
bool inq[maxn];
queue<int>Q;
struct node{
    int next,to,c[4];
}e[maxn<<1];
inline void ins(int from,int to,int c1,int c2,int c3){
    e[++tot].next=head[from];
    e[tot].to=to; e[tot].c[1]=c1; e[tot].c[2]=c2; e[tot].c[3]=c3;
    head[from]=tot;
}
void spfa(int x,int k){
    Q.push(x); dis[k][x]=0; inq[x]=1;
    do{
        int u=Q.front(); Q.pop(); inq[u]=0;
        for(int i=head[u];i;i=e[i].next)
        if(dis[k][e[i].to]>dis[k][u]+e[i].c[k]){
            dis[k][e[i].to]=dis[k][u]+e[i].c[k];
            if(!inq[e[i].to]) Q.push(e[i].to),inq[e[i].to]=1;
        }
    }while(!Q.empty());
}
int main(){
    read(n);read(m);
    for(int i=1;i<=m;++i){
        read(u[i]);read(v[i]);read(p[i]);read(q[i]);
        ins(v[i],u[i],p[i],q[i],0);
    }
    memset(dis,0x3f,sizeof(dis));
    spfa(n,1); spfa(n,2);
    tot=0; memset(head,0,sizeof(head));
    for(int i=1;i<=m;++i){
        int w=2;
        if(dis[1][u[i]]-dis[1][v[i]]==p[i]) --w;
        if(dis[2][u[i]]-dis[2][v[i]]==q[i]) --w;
        ins(u[i],v[i],0,0,w);
    }
    spfa(1,3);
    printf("%d\n",dis[3][n]);
    return 0;
}

 

posted @ 2017-10-30 22:32  沐灵_hh  阅读(210)  评论(0编辑  收藏  举报