zoukankan      html  css  js  c++  java
  • 回家

    Description
    moreD城的城市轨道交通建设终于全部竣工,由于前期规划周密,建成后的轨道交通网络由 2n 条地铁线路构成,组成了一个 n 纵 n 横的交通网。如下图所示,这 2n 条线路每条线路都包含 n 个车站,而每个车站都在一组纵横线路的交汇处。

    出于建设成本的考虑,并非每个车站都能够进行站内换乘,能够进行站内换乘的地铁站共有 m 个,在下图中,标上方块标记的车站为换乘车站。已知地铁运行 1 站需要 2 分钟,而站内换乘需要步行 1 分钟。 你的最后一个作业就是算出,在不中途出站的前提下,从学校回家最快需要多少时间(等车时间忽略不计)。

    在这里插入图片描述

    Input
    第一行有两个整数 n, m。接下去 m 行每行两个整数 x, y,表示第 x 条横向线路与第 y 条纵向线路的交汇站是站内换乘站。接下去一行是四个整数 x1, y1, x2, y2。表示从学校回家时,在第 x1条横向线路与第 y1 条纵向线路的交汇站上车,在第 x2 条横向线路与第 y2 条纵向线路的交汇站下车。

    Output
    仅一个整数表示在合理选择线路的情况下,回家所需要的最少时间。如果无法在不出站换车的情况下回家则输出-1.

    Sample Input
    Sample Input 1
    6 9
    2 1
    2 5
    3 2
    4 4
    5 2
    5 6
    6 1
    6 3
    6 4
    1 1 4 6

    Sample Input 2
    6 10
    2 1
    2 5
    3 2
    4 4
    5 2
    5 6
    6 1
    6 3
    6 4
    6 6
    1 1 4 6

    Sample Input 3
    2 1
    1 2
    1 1 2 2

    Sample Output
    Sample Output 1
    27

    Sample Output 2
    26

    Sample Output 3
    5

    Data Constraint

    Hint
    对于10%的数据m=0
    对于 30%的数据,n ≤ 50, m ≤ 1000;
    对于 60%的数据,n ≤ 500, m ≤ 2000;
    对于 100%的数据,n ≤ 20000, m ≤ 100000;

    .
    .
    .
    .
    .
    分析
    题目大意:给定一个nn的图,有n个可以转向的交点(横纵变化),每次转向需要1的代价,每走一个站需要2的代价,问从起点到终点的最小代价
    显然,我们可以对于一个点拆成两个点(横纵),然后对于每个转向的点的横纵相连,代价为1
    同行同列相连,代价为距离
    2,起点和终点横纵转换可以不用代价,因为可以起点可以任意开始,终点也可以从上下到达
    建完图就可以直接跑spfa

    .
    .
    .
    .
    .
    程序:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int n,m,cnt=0,d[200010],inf=0X7f,f[200010],head[800010];
    queue<int>q;
    
    struct node
    {
    	int to,from,v;
    } e[800010];
    
    struct edge
    {
    	int x,y,id;
    } a[200010];
    
    bool cmp1(edge a,edge b)
    {
    	if (a.x==b.x) return a.y<b.y;
    	return a.x<b.x;
    }
    
    bool cmp2(edge a,edge b)
    {
    	if (a.y==b.y) return a.x<b.x;
    	return a.y<b.y;
    }
    
    void add(int x,int y,int v)
    {
    	e[++cnt].to=y;e[cnt].from=head[x];e[cnt].v=v;head[x]=cnt;
    	e[++cnt].to=x;e[cnt].from=head[y];e[cnt].v=v;head[y]=cnt;
    }
    
    int spfa()
    {
        memset(d,inf,sizeof(d));
        q.push(m+1); 
        d[m+1]=0;
        f[m+1]=1;
        while (!q.empty())
        {
            int u=q.front(); 
            q.pop();
            f[u]=0;
            for (int i=head[u];i;i=e[i].from)
            {
            	if (d[u]+e[i].v<d[e[i].to])
                {
                	d[e[i].to]=d[u]+e[i].v;
            		if (f[e[i].to]==0) 
            		{
            			q.push(e[i].to);
            			f[e[i].to]=1;
    				}
    			}
            }
        }
        if (d[m+2]==inf) return -1; else return d[m+2];
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	
    	if (m==0)
    	{
    		int x1,y1,x2,y2;
    		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    		if (x1!=x2&&y1!=y2)
    		{
    			printf("-1");
    			return 0;
    		}
    	}
    	for (int i=1;i<=m+2;i++)
    	{
    		scanf("%d%d",&a[i].x,&a[i].y);
    		a[i].id=i;
    	}
    	sort(a+1,a+m+1+2,cmp1);  
    
    	
    	
    	for (int i=1;i<=m+1;i++)
        	if (a[i].x==a[i+1].x) add(a[i].id,a[i+1].id,(a[i+1].y-a[i].y)*2);
        
        sort(a+1,a+m+1+2,cmp2);
        
        for (int i=1;i<=m+1;i++)
        	if (a[i].y==a[i+1].y) add(a[i].id+m+2,a[i+1].id+m+2,(a[i+1].x-a[i].x)*2);
        for (int i=1;i<=m;i++)
        	add(i,i+m+2,1);
        add(m+1,m*2+3,0);
        add(m+2,m*2+4,0);
    	printf("%d",spfa());
    	return 0;
    }
    
  • 相关阅读:
    十大接口
    ORM表之间高级设计
    响用模块
    异常模块的使用
    解析模块的使用
    渲染模板
    通达OA 11.7 后台sql注入getshell漏洞复现
    通达OA 11.5 SQL注入漏洞复现
    ThinkAdminV6 未授权访问and 任意文件查看 漏洞复现
    用友GRP-u8 XXE 漏洞复现
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/10458939.html
Copyright © 2011-2022 走看看