zoukankan      html  css  js  c++  java
  • 【bzoj2834】回家的路 分层图最短路

    题目描述

    输入

    输出

    样例输入

    2 1
    1 2
    1 1 2 2

    样例输出

    5


    题解

    分层图最短路

    dis[i][0]表示到i为横向时起点到i的最短路,dis[i][1]表示到i为纵向时起点到i的最短路。

    然后把同行列相邻的节点连边建图,跑一下就行了。

    然而题目中可能出现起点或终点与换乘站重复的情况,所以必须横竖两种情况全强行判断,不能以为横着的就不是竖着的,否则会无限WA。

    #include <cstdio>
    #include <cstring>
    #include <utility>
    #include <queue>
    #include <algorithm>
    using namespace std;
    queue<pair<int , int> > q;
    struct data
    {
    	int x , y , pos;
    }a[100010];
    int head[100010] , to[800010] , next[800010] , cnt , inq[100010][2];
    long long len[800010] , dis[100010][2];
    bool cmpx(data a , data b)
    {
    	return a.x == b.x ? a.y < b.y : a.x < b.x;
    }
    bool cmpy(data a , data b)
    {
    	return a.y == b.y ? a.x < b.x : a.y < b.y;
    }
    bool cmpp(data a , data b)
    {
    	return a.pos < b.pos;
    }
    void add(int x , int y , long long z)
    {
    	to[++cnt] = y;
    	len[cnt] = z;
    	next[cnt] = head[x];
    	head[x] = cnt;
    }
    int main()
    {
    	int n , m , i , tx , p;
    	pair<int , int> u;
    	scanf("%d%d" , &n , &m);
    	for(i = 1 ; i <= m ; i ++ )
    		scanf("%d%d" , &a[i].x , &a[i].y);
    	scanf("%d%d%d%d" , &a[0].x , &a[0].y , &a[m + 1].x , &a[m + 1].y);
    	for(i = 0 ; i <= m + 1 ; i ++ )
    		a[i].pos = i;
    	sort(a , a + m + 2 , cmpx);
    	for(i = 0 ; i <= m ; i ++ )
    		if(a[i].x == a[i + 1].x)
    			add(a[i].pos , a[i + 1].pos , 2 * (a[i + 1].y - a[i].y)) , add(a[i + 1].pos , a[i].pos , 2 * (a[i + 1].y - a[i].y));
    	sort(a , a + m + 2 , cmpy);
    	for(i = 0 ; i <= m ; i ++ )
    		if(a[i].y == a[i + 1].y)
    			add(a[i].pos , a[i + 1].pos , 2 * (a[i + 1].x - a[i].x)) , add(a[i + 1].pos , a[i].pos , 2 * (a[i + 1].x - a[i].x));
    	sort(a , a + m + 2 , cmpp);
    	memset(dis , 0x3f , sizeof(dis));
    	dis[0][0] = dis[0][1] = 0;
    	inq[0][0] = inq[0][1] = 1;
    	q.push(make_pair(0 , 0));
    	q.push(make_pair(0 , 1));
    	while(!q.empty())
    	{
    		u = q.front();
    		q.pop();
    		tx = u.first;
    		p = u.second;
    		inq[tx][p] = 0;
    		for(i = head[tx] ; i ; i = next[i])
    		{
    			if(!p && a[tx].x == a[to[i]].x || p && a[tx].y == a[to[i]].y)
    			{
    				if(dis[to[i]][p] > dis[tx][p] + len[i])
    				{
    					dis[to[i]][p] = dis[tx][p] + len[i];
    					if(!inq[to[i]][p]) inq[to[i]][p] = 1 , q.push(make_pair(to[i] , p));
    				}
    			}
    			if(p && a[tx].x == a[to[i]].x || !p && a[tx].y == a[to[i]].y)
    			{
    				if(dis[to[i]][p ^ 1] > dis[tx][p] + len[i] + 1)
    				{
    					dis[to[i]][p ^ 1] = dis[tx][p] + len[i] + 1;
    					if(!inq[to[i]][p ^ 1]) inq[to[i]][p ^ 1] = 1 , q.push(make_pair(to[i] , p ^ 1));
    				}
    			}
    		}
    	}
    	printf("%lld
    " , min(dis[m + 1][0] , dis[m + 1][1]) == 0x3f3f3f3f3f3f3f3fll ? -1 : min(dis[m + 1][0] , dis[m + 1][1]));
    	return 0;
    }

     

  • 相关阅读:
    Sublime Text 3 快捷键精华版
    css动画+滚动的+飞舞的小球
    css动画+照片清晰度动画
    simhash
    抛弃IIS,利用FastCGI让Asp.net与Nginx在一起
    不逃离WIndows,Asp.Net就只能写写进销存管理系统
    吸引下百度蜘蛛
    Arcpy功能总结
    英雄杀
    NCEP Datasets
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6486152.html
Copyright © 2011-2022 走看看