【SHOI2012】回家的路

2046年OI城的城市轨道交通建设终于全部竣工,由于前期规划周密,建成后的轨道交通网络由2n条地铁
线路构成,组成了一个n纵n横的交通网。如下图所示,这2n条线路每条线路都包含n个车站,而每个车站
都在一组纵横线路的交汇处。
出于建设成本的考虑,并非每个车站都能够进行站内换乘,能够进行站内换乘的地铁站共有m个,在下图
中,标上方块标记的车站为换乘车站。已知地铁运行1站需要2分钟,而站内换乘需要步行1分钟。
Serenade想要知道,在不中途出站的前提下,他从学校回家最快需要多少时间(等车时间忽略不计)

具体的题解明天写吧 回寝室睡觉了

#include <bits/stdc++.h>
#define N 400005
#define M 2000005
using namespace std;

int n,m,S,T;

struct Edge
{
    int next,to,dis;
}edge[M];
int cnt=0,head[N];

template<class T>inline void read(T &res)
{
    char c;T flag=1;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}

struct Road
{
    int x,y,id;
} a[N];

struct Node
{
    int v,id;
    inline friend bool operator<(Node x, Node y) {return x.v>y.v;}
};

inline void add_edge(int from,int to,int dis)
{
    edge[++cnt].next=head[from];
    edge[cnt].to=to;
    edge[cnt].dis=dis;
    head[from]=cnt;
}

inline bool cmp1(Road a,Road b) {return a.x==b.x?a.y<b.y:a.x<b.x;}

inline bool cmp2(Road a,Road b) {return a.y==b.y?a.x<b.x:a.y<b.y;}

int dis[N+5];
bool vis[N+5];
inline void dijkstra(int u)
{
    priority_queue<Node> q;
    memset(dis,0x3f,sizeof(dis));
    dis[u]=0;
    q.push((Node){0,u});
    while(!q.empty())
    {
        int u=q.top().id;
        q.pop();
        if(vis[u]) continue;
        vis[u]=1;
        for(register int i=head[u];i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(dis[v]>dis[u]+edge[i].dis)
            {
                dis[v]=dis[u]+edge[i].dis;
                if(!vis[v]) q.push((Node){dis[v],v});
            }
        }
    }
}

int main()
{
    read(n);read(m);
    n=m+2;
    S=n-1;
    T=n;
    for(register int i=1;i<=n;++i)
    {
        read(a[i].x);
        read(a[i].y);
        a[i].id=i;
    }
    sort(a+1,a+n+1,cmp1);
    for(register int i=1;i<n;++i)
    {
        if(a[i].x==a[i+1].x)
        {
            add_edge(a[i].id,a[i+1].id,(a[i+1].y-a[i].y)<<1);
            add_edge(a[i+1].id,a[i].id,(a[i+1].y-a[i].y)<<1);
        }
    }
    sort(a+1,a+n+1,cmp2);
    for(register int i=1;i<n;++i)
    {
        if(a[i].y==a[i+1].y)
        {
            add_edge(a[i].id+n,a[i+ 1].id+n,(a[i+1].x-a[i].x)<<1);
            add_edge(a[i+1].id+n,a[i].id+n,(a[i+1].x-a[i].x)<<1);
        }
    }
    for(register int i=1;i<=n-2;++i)
    {
        add_edge(i,i+n,1);
        add_edge(i+n,i,1);
    }
    add_edge(S,S+n,0);
    add_edge(S+n,S,0);
    add_edge(T,T+n,0);
    add_edge(T+n,T,0);
    dijkstra(S);
    printf(dis[T]==0x3f3f3f3f?"-1\n":"%d\n",dis[T]);
    return 0;
}

原文地址:https://www.cnblogs.com/tqr06/p/11625928.html

时间: 2024-10-06 13:40:27

【SHOI2012】回家的路的相关文章

[SHOI2012]回家的路 最短路

---题面--- 题解: 吐槽:找了好久的错,换了n种方法,重构一次代码,,,, 最后发现,,, 数组开小了,其实一开始尝试开大了数组,但唯独没有尝试开大手写队列的数组.... 思路: 有两种方法,这里都介绍一下吧,分别在时间复杂度和代码复杂度上各有优势. 第一种:时间复杂度更优,代码复杂 观察到转弯时需要多消耗1的费用,不转弯则不用.因此我们记录一个last表示这个点的最短路是从哪走来的.(其实就是记录路径) 然后注意到A ---> C 与A ---> B ---> C是等效的,因此我

Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路

2834: 回家的路 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 62  Solved: 38[Submit][Status][Discuss] Description Input Output Sample Input 2 1 1 2 1 1 2 2 Sample Output 5 HINT N<=20000,M<=100000 Source dijkstra+堆优化+分层图 把所有的横向和纵向分开看.跑最短路即可. 注意:N这么大,不能写

看到故乡的方向,找到回家的路

朋友从故乡归来,闷闷不乐,问之,他说老家村庄的一棵古树被村里人卖了.他从小在这棵树下长大,对这棵树很有感情.现在这棵树没了,总感觉内心失落落的,故乡不再是完整的故乡了. 我理解他对这棵树的感情.如果说故乡是他储存童年.少年记忆的仓库,那么这棵树,就是一把钥匙,能打开这个仓库的门. 似乎每个从乡村走出来的人,心里都有这么一棵或者几棵树吧.反正我就有.是一棵柏树,古柏,两抱之粗.树龄究竟有几百年,村里没人能说得出来.即使村里如今最年长的康田大爷,也只是说,从他小的时候,树就这么粗. 古柏立在村口,守

你一定不要忘记了回家的路:自己的心灵世界

生活在今日的世界上,心灵的宁静不易得.这个世界既充满着机会,也充满着压力.机会诱惑人去尝试,压力逼迫人去奋斗,都使人静不下心来.我不主张年轻人拒绝任何机会,逃避一切压力,以闭关自守的姿态面对世界.年轻的心灵本不该静如止水,波澜不起.世界是属于年轻人的,趁着年轻到广阔的世界上去闯荡一番,原是人生必要的经历.所须防止的只是,把自己完全交给了机会和压力去支配,在世界上风风火火或浑浑噩噩,迷失了回家的路途. 每到一个陌生的城市,我的习惯是随便走走,好奇心驱使我去探寻这里的热闹的街巷和冷僻的角落.在这途中

记住回家的路

记住回家的路------周国平 生活在今日的世界上,心灵的宁静不易得.这个世界既充满着机会,也充满着压力.机会诱惑人去尝试,压力逼迫人去奋斗,都使人静不下心来.我不主张年轻人拒绝任何机会,逃避一切压力,以闭关自守的姿态面对世界.年轻的心灵本不该静如止水,波澜不起.世界是属于年轻人的,趁着年轻到广阔的世界上去闯荡一番,原是人生必要的经历.所须防止的只是,把自己完全交给了机会和压力去支配,在世界上风风火火或浑浑噩噩,迷失了回家的路途. 每到一个陌生的城市,我的习惯是随便走走,好奇心驱使我去探寻这里的

别陌生了回家的路

最让人不能放下的莫过于日渐老去的父母,最让人归心似箭的莫过于家.岁月默然远去,这种情怀总会历久热切的. 人生之旅,很像一只候鸟,南来北往,北往南来,远离亲人,浪迹天涯处.春日里忘我地耕耘,夏日里艰辛的劳作,期待能在人生之秋有所丰硕.漫漫人生之旅,无论何以繁华,何以鼎盛,总会在人生的渡口,不经意间,回首故土,回首老屋,萌生一种对父母的牵念.倘若岁月静好,父母康健,心里就多了一抹暖. 一个大雪纷纷的冬日,终告别了那一段贫瘠和苦涩的日子,踏上了北去的列车,成为一名空军战士.然而,家,在心田里从没有远去

使用 Power BI 分析 “回家的路”

很多年以前,不知道怎么就听说,有个小小的转换器,能够把汽车CAN总线转接为串口,然后,就出现了再转成蓝牙或者WIFI接口的小设备.这个小设备能够获取OBD II标准的数据.OBD II的标准广泛用在各种汽车控制器上,能够通过这些数据获得汽车的各种状态数据和告警. 于是很多牛人基于这个小玩意,在电脑特别是手机上开发了不少应用.通过蓝牙或者WIFI获得数据后,处理显示出来.数据的使用多种多样,例如自定义仪表,然后利用挡风玻璃实现HUD抬头显示,利用手机对简单的故障告警进行清楚(消码)-我当时也很有兴

BZOJ 2834 回家的路

分层图最短路.边要开够. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define maxv 300500 #define maxe 2000500 #define inf 2147483647 using namespace std; struct pnt { int x,y,id; }p[maxv]; st

解题:SHOI 2012 回家的路

题面 完了,做的时候已经想不起来分层图这个东西了QAQ 对于这种"多种"路径加中转站的题,还有那种有若干次"特殊能力"的题,都可以考虑用分层图来做 显然只需要记录所有的中转站+起点终点,然后拆出横竖两层,一层的点之间连值为$2$的边,每个站的两层之间连值为$1$的边,然后再跑最短路.注意数组大小,还有起点和终点的两层是连零边的 1 #include<queue> 2 #include<cstdio> 3 #include<cstring