zoukankan      html  css  js  c++  java
  • Guide AHOI2017 洛谷P3720

    Description

    农场主John最近在网上买了一辆新车,在购买汽车配件时,John不小心点了两次“提交”按钮。导致汽车上安装了两套GPS系统,更糟糕的是John在使用GPS导航时,两套系统常常给出不同的路线。从地图上看,John居住的地区有N个十字路口和M条限定通行方向的道路。第i条道路连接路口A_i(1≤A_i≤N)和B_i(1≤B_i≤N),两个路口之间可能连接有多条道路。允许双向通⾏的道路是将两条单向通⾏的道路隔开所形成的。

    John的家在路口1位置,农场在路口N的位置。John可以沿着⼀系列单向道路从家驾车到农场。所有GPS系统的底层地图信息都是⼀样的,区别仅在于对每一条道路的通⾏时间计算不同。对于第i条道路第一套GPS系统计算通行时间为P_i个单位时间,而第二套GPS系统则给出Q_i个单位时间。(所有道路的通行时间都是范围在1到100,000之间的整数)John想要驾车从家到农场。可是,一路上GPS系统总是不厌其烦的提醒John(请从路口X开往路口Y),这是由于John选取了某套GPS系统建议的路径,而另一套GPS系统则认为这不是从路口X到农场的最短路径。我们称之为GPS系统的抱怨。

    请你计算一下如果John选择合适的路径到达农场能听到的最少GPS系统的抱怨数 。如果John经过某条道路两套GPS系统都发出抱怨,则抱怨总数加2。


    Input

    第一行,两个整数N和M。接下来M行,其中第i行描述了道路i的信息,A_i B_i P_i Q_i。


    Output

    一个整数,表示John一路上能听到的最小抱怨数。


    Hint

    2≤N≤100000,1≤M≤500000。


    Solution

    洛谷上面的题都坑爹得一批,指针也坑爹得一批,然后这道题成功地两条都应验了。。。


    呃这道题首先是个最短路然后要建三张图跑三次,Dijkstra和SPFA好像都可以不过为了复习SPFA我还是写的SPFA即使它非常地坑人。。嗯然后两个GPS的最短路径各跑一遍,然后用一个for循环预处理出第三个图的边权,也就是这个听抱怨的图的边权,然后只要他没有听GPS1或者2的都要++,都没听就会++两次,然后最后再跑一次SPFA就可以了。


    注意事项:
    1.指针不能sizeof我要是再被这个坑了我就去自杀一百遍。。。
    2.这个因为最后到的是n所以既然是单源最短路径就要从n开始,而且,而且,而且,要,建,反图。
    3.好的我还是傻逼还是非常地弱,没了。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #define maxn 500005
    #define inf 0x3f3f3f3f
    using namespace std;
    int n,m,node1,x,y,z1,z2,node2,node3;
    struct Edge{
    	int u;
    	int v;
    	int w;
    	int next;
    }edge1[maxn],edge2[maxn],edge3[maxn];
    int first1[maxn],last1[maxn],first2[maxn];
    int last2[maxn],first3[maxn],last3[maxn];
    int dist1[maxn],dist2[maxn],dist3[maxn];
    bool vis1[maxn],vis2[maxn],vis3[maxn];
    void addedge1(int u,int v,int w){
    	edge1[++node1]=(Edge){u,v,w,0};
    	if(first1[u]==0)first1[u]=node1;
    	else edge1[last1[u]].next=node1;
    	last1[u]=node1;
    }
    void addedge2(int u,int v,int w){
    	edge2[++node2]=(Edge){u,v,w,0};
    	if(first2[u]==0)first2[u]=node2;
    	else edge2[last2[u]].next=node2;
    	last2[u]=node2;
    }
    void addedge3(int u,int v,int w){
    	edge3[++node3]=(Edge){u,v,w,0};
    	if(first3[u]==0)first3[u]=node3;
    	else edge3[last3[u]].next=node3;
    	last3[u]=node3;
    }
    void init(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d%d",&x,&y,&z1,&z2);
    		addedge1(y,x,z1);
    		addedge2(y,x,z2);
    		addedge3(y,x,0);
    	}
    }
    void spfa1(int s,int *d){
    	queue<int>pq;
    	memset(d,inf,sizeof(dist1));
    	d[s]=0;
    	vis1[s]=true;
    	pq.push(s);
    	while(!pq.empty()){
    		int u=pq.front();
    		pq.pop();
    		vis1[u]=false;
    		for(int k=first1[u];k;k=edge1[k].next){
    			int v=edge1[k].v;
    			if(d[u]+edge1[k].w<=d[v]){
    				d[v]=d[u]+edge1[k].w;
    				if(!vis1[v]){
    					vis1[v]=true;
    					pq.push(v);
    				}
    			}
    		}
    	}
    }
    void spfa2(int s,int *d){
    	queue<int>pq;
    	memset(d,inf,sizeof(dist2));
    	d[s]=0;
    	vis2[s]=true;
    	pq.push(s);
    	while(!pq.empty()){
    		int u=pq.front();
    		pq.pop();
    		vis2[u]=false;
    		for(int k=first2[u];k;k=edge2[k].next){
    			int v=edge2[k].v;
    			if(d[u]+edge2[k].w<=d[v]){
    				d[v]=d[u]+edge2[k].w;
    				if(!vis2[v]){
    					vis2[v]=true;
    					pq.push(v);
    				}
    			}
    		}
    	}
    }
    void spfa3(int s,int *d){
    	queue<int>pq;
    	memset(d,inf,sizeof(dist3));
    	d[s]=0;
    	vis3[s]=true;
    	pq.push(s);
    	while(!pq.empty()){
    		int u=pq.front();
    		pq.pop();
    		vis3[u]=false;
    		for(int k=first3[u];k;k=edge3[k].next){
    			int v=edge3[k].v;
    			if(d[u]+edge3[k].w<=d[v]){
    				d[v]=d[u]+edge3[k].w;
    				if(!vis3[v]){
    					vis3[v]=true;
    					pq.push(v);
    				}
    			}
    		}
    	}
    }
    int main(){
    	init();
    	spfa1(n,dist1);
    	spfa2(n,dist2);
    	for(int i=1;i<=n;i++){
    		for(int k=first3[i];k;k=edge3[k].next){
    			int u=edge3[k].v;
    			if(dist1[i]+edge1[k].w!=dist1[u])edge3[k].w++;
    			if(dist2[i]+edge2[k].w!=dist2[u])edge3[k].w++;
    		}
    	}
    	spfa3(n,dist3);
    	printf("%d
    ",dist3[1]);
    	return 0;
    }
    
  • 相关阅读:
    美化博客园
    ansible的安装
    面向对象和类
    函数知识分类
    生成器
    内置函数_old
    迭代器
    装饰器
    Hadoop——MapReduce
    Hadoop——HDFS
  • 原文地址:https://www.cnblogs.com/virtual-north-Illya/p/10045162.html
Copyright © 2011-2022 走看看