zoukankan      html  css  js  c++  java
  • [BZOJ3538]坑爹的GPS

    题目描述 Description###

    有一天,(FJ) 买了一辆车,但是,他一手下载了两个(GPS) 系统。好了现在麻烦的事情来了,(GPS) 有一个功能大概大家也知道,如果(FJ) 没有按照(GPS) 内置地图的最短路走,(GPS) 就会报错来骚扰你。现在(FJ) 准备从他的农舍(在1这个点)开车到他的谷屋((n) 这个点)。(FJ) 给了你两个(GPS) 系统内置地图的信息,他想知道,他最少会听到多少次报错(如果(FJ) 走的路同时不满足两个(GPS) ,报错次数+2)

    输入描述 Input Description###

    第一行:(n) ,(k)(n) 表示有(FJ) 的谷屋在哪,同时保证(GPS) 内置地图里的点没有超过(n) 的点。(K) 表示(GPS) 内置地图里的路有多少条,如果两个点没有连接则表明这不是一条通路。
    接下来(k) 行,每行4个数(X) ,(Y) ,(A) ,(B) 分别表示从(X)(Y) 在第一个(GPS) 地图里的距离是(A) ,在第二个(GPS) 地图里的是(B) 。注意由于地形的其他因素(GPS) 给出的边是有向边。

    输出描述 Output Description###

    一个值,表示(FJ) 最少听到的报错次数。

    样例输入 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
    

    样例输出 Sample Output###

    1
    

    数据范围及提示 Data Size & Hint###

    (FJ) 选择的路线是1 2 4 5,但是(GPS) 1认为的最短路是1到3,所以报错一次,对于剩下的2 4 5,两个(GPS) 都不会报错。
    (N<=10000) ,至于路有多少条自己算吧。数据保证所有的距离都在$2^{31}-1 $ 以内。

    之前的一些废话###

    离期中还有两周,离NOIP还有不到三周,下午开始停课计划,是时候拼了!

    题解###

    对于第一个(GPS) 求一遍最短路,对第二个也求一遍最短路,注意是以(n) 为源点进行最短路,所以还要存一个反图。然后我们尝试建一个报错的地图。在原图上搜索,对于一条边,如果走这一条边不满足第一个(GPS) 上的最短路这条路边权加一,同理判断是否第二个的(GPS) ,建好图之后再跑一个最短路即可。

    代码###

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> PII;
    #define mem(a,b) memset(a,b,sizeof(a))
    inline int read()
    {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    	return x*f;
    }
    const int maxn=10010,maxm=50010;
    struct Edge
    {
    	int u,v,w1,w2,next;
    	Edge() {}
    	Edge(int _1,int _2,int _3,int _4,int _5):u(_1),v(_2),w1(_3),w2(_4),next(_5) {}
    }e[maxm<<1],rev[maxm<<1],E[maxm<<1];
    int n,m,first[maxn],rfirst[maxn],First[maxn],c1=-1,c2=-1,ce=-1,a,b,c,d,dis1[maxn],dis2[maxn],dis3[maxn];
    bool vis[maxn];
    queue<int> Q;
    void addEdge(int a,int b,int c,int d)
    {
    	e[++c1]=Edge(a,b,c,d,first[a]);first[a]=c1;
    	rev[++c2]=Edge(b,a,c,d,rfirst[b]);rfirst[b]=c2;
    }
    void AddEdge(int a,int b,int c){E[++ce]=Edge(a,b,c,0,First[a]);First[a]=ce;}
    void SPFA1()
    {
    	mem(vis,0);mem(dis1,42);
    	while(Q.size())Q.pop();
    	Q.push(n);vis[n]=1;dis1[n]=0;
    	while(Q.size())
    	{
    		int now=Q.front();Q.pop();
    		for(int i=rfirst[now];i!=-1;i=rev[i].next)
    		    if(dis1[now]+rev[i].w1<dis1[rev[i].v])
    		    {
    		    	dis1[rev[i].v]=dis1[now]+rev[i].w1;
    		    	if(!vis[rev[i].v])
    				{
    					Q.push(rev[i].v);
    					vis[rev[i].v]=1;
    				} 
    			}
    		vis[now]=0;
    	}
    	return;
    }
    void SPFA2()
    {
    	mem(vis,0);mem(dis2,42);
    	while(Q.size())Q.pop();
    	Q.push(n);vis[n]=1;dis2[n]=0;
    	while(Q.size())
    	{
    		int now=Q.front();Q.pop();
    		for(int i=rfirst[now];i!=-1;i=rev[i].next)
    		    if(dis2[now]+rev[i].w2<dis2[rev[i].v])
    		    {
    		    	dis2[rev[i].v]=dis2[now]+rev[i].w2;
    		    	if(!vis[rev[i].v])
    				{
    					Q.push(rev[i].v);
    					vis[rev[i].v]=1;
    				} 
    			}
    		vis[now]=0;
    	}
    	return;
    }
    void SPFA3()
    {
    	mem(vis,0);mem(dis3,42);
    	while(Q.size())Q.pop();
    	Q.push(1);vis[1]=1;dis3[1]=0;
    	while(Q.size())
    	{
    		int now=Q.front();Q.pop();
    		for(int i=First[now];i!=-1;i=E[i].next)
    		    if(dis3[now]+E[i].w1<dis3[E[i].v])
    		    {
    		    	dis3[E[i].v]=dis3[now]+E[i].w1;
    		    	if(!vis[E[i].v])
    				{
    					Q.push(E[i].v);
    					vis[E[i].v]=1;
    				} 
    			}
    		vis[now]=0;
    	}
    	return;
    }
    int main()
    {
    	mem(first,-1);mem(rfirst,-1);mem(First,-1);
    	n=read();m=read();
    	for(int i=1;i<=m;i++)a=read(),b=read(),c=read(),d=read(),addEdge(a,b,c,d);
    	SPFA1();SPFA2();
    	for(int point=1;point<=n;point++)
    		for(int i=first[point];i!=-1;i=e[i].next)
    		{
    			int cnt=0;
    			if(dis1[point]!=dis1[e[i].v]+e[i].w1)cnt++;
    			if(dis2[point]!=dis2[e[i].v]+e[i].w2)cnt++;
    			AddEdge(point,e[i].v,cnt);
    		}
    	SPFA3();
    	printf("%d
    ",dis3[n]);
    	return 0;
    }
    
    

    总结###

    还是比较套路的。

  • 相关阅读:
    STM32 F4 DAC DMA Waveform Generator
    STM32 F4 General-purpose Timers for Periodic Interrupts
    Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式
    Python第十三天 django 1.6 导入模板 定义数据模型 访问数据库 GET和POST方法 SimpleCMDB项目 urllib模块 urllib2模块 httplib模块 django和web服务器整合 wsgi模块 gunicorn模块
    查看SQL Server服务运行帐户和SQL Server的所有注册表项
    Pycharm使用技巧(转载)
    SQL Server 2014内存优化表的使用场景
    Python第十天 print >> f,和fd.write()的区别 stdout的buffer 标准输入 标准输出 从控制台重定向到文件 标准错误 重定向 输出流和输入流 捕获sys.exit()调用 optparse argparse
    Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数
    Python第六天 类型转换
  • 原文地址:https://www.cnblogs.com/FYH-SSGSS/p/7719041.html
Copyright © 2011-2022 走看看