• 【JZOJ3086】【洛谷P3831】回家【最短路】


    题目大意:

    题目链接:

    JZOJ:https://jzoj.net/senior/#main/show/3086
    洛谷:https://www.luogu.org/problemnew/show/P3831

    moreDmoreD城的城市轨道交通建设终于全部竣工,由于前期规划周密,建成后的轨道交通网络由 2n2n条地铁线路构成,组成了一个nnnn横的交通网。如下图所示,这2n2n条线路每条线路都包含nn个车站,而每个车站都在一组纵横线路的交汇处。
    出于建设成本的考虑,并非每个车站都能够进行站内换乘,能够进行站内换乘的地铁站共有mm 个,在下图中,标上方块标记的车站为换乘车站。已知地铁运行11站需要22分钟,而站内换乘需要步行11分钟。 你的最后一个作业就是算出,在不中途出站的前提下,从学校回家最快需要多少时间(等车时间忽略不计)。
    在这里插入图片描述


    思路:

    每个点拆成横点和竖点,之间连一条长度为11的边作为转站时间。
    若两个点在同一行或同一列,之间连上长度的22倍的边。
    跑最短路即可。注意连边时需要排序连边,保证复杂度。
    时间复杂度:O(n logn)O(n logn)


    代码:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #define mp make_pair
    using namespace std;
    
    const int N=200010;
    int n,m,S,T,tot,head[N],dis[N],id[N];
    bool vis[N];
    priority_queue<pair<int,int> > q;
    
    struct edge
    {
    	int to,dis,next;
    }e[N*4];
    
    struct station
    {
    	int x,y;
    }a[N];
    
    void add(int from,int to,int dis)
    {
    	e[++tot].to=to;
    	e[tot].dis=dis;
    	e[tot].next=head[from];
    	head[from]=tot;
    }
    
    bool cmp1(int x,int y)
    {
    	return a[x].x<a[y].x||(a[x].x==a[y].x&&a[x].y<a[y].y);
    }
    
    bool cmp2(int x,int y)
    {
    	return a[x].y<a[y].y||(a[x].y==a[y].y&&a[x].x<a[y].x);
    }
    
    void dij()
    {
    	memset(dis,0x3f3f3f3f,sizeof(dis));
    	q.push(mp(0,S));
    	dis[S]=0;
    	vis[S]=1;
    	while (q.size())
    	{
    		int u=q.top().second;
    		q.pop();
    		for (int i=head[u];~i;i=e[i].next)
    		{
    			int v=e[i].to;
    			if (dis[v]>dis[u]+e[i].dis)
    			{
    				dis[v]=dis[u]+e[i].dis;
    				if (!vis[v])
    				{
    					q.push(mp(-dis[v],v));
    					vis[v]=1;
    				}
    			}
    		}
    	}
    }
    
    int main()
    {
    	memset(head,-1,sizeof(head));
    	scanf("%d%d",&n,&m);
    	m+=2;
    	for (int i=1;i<=m-2;i++)
    	{
    		scanf("%d%d",&a[i].x,&a[i].y);
    		id[i]=i;
    	}
    	S=m-1; T=m;
    	scanf("%d%d",&a[S].x,&a[S].y); id[S]=S;
    	scanf("%d%d",&a[T].x,&a[T].y); id[T]=T;
    	sort(id+1,id+1+m,cmp1);
    	for (int i=1;i<m;i++)
    		if (a[id[i]].x==a[id[i+1]].x)
    		{
    			add(id[i],id[i+1],(a[id[i+1]].y-a[id[i]].y)*2);
    			add(id[i+1],id[i],(a[id[i+1]].y-a[id[i]].y)*2);
    		}
    	sort(id+1,id+1+m,cmp2);
    	for (int i=1;i<m;i++)
    		if (a[id[i]].y==a[id[i+1]].y)
    		{
    			add(id[i]+m,id[i+1]+m,(a[id[i+1]].x-a[id[i]].x)*2);
    			add(id[i+1]+m,id[i]+m,(a[id[i+1]].x-a[id[i]].x)*2);
    		}
    	add(T,T+m,0); add(T+m,T,0);
    	add(S,S+m,0); add(S+m,S,0);
    	for (int i=1;i<=m-2;i++)
    		add(i,i+m,1),add(i+m,i,1);
    	dij();
    	if (min(dis[T],dis[T+m])<1e9) printf("%d
    ",min(dis[T],dis[T+m]));
    		else printf("-1
    ");
    	return 0;
    }
    
  • 相关阅读:
    Fiddler 抓取Https时 显示 Tunnel to 443 的解决方案2
    Fiddler 抓取Https时 显示 Tunnel to 443 的解决方案
    Fiddler 模拟器抓包,SSL抓包不到
    2021 CSP-S初赛游记
    停课日志(持续更新ing)
    洛谷 P4587 [FJOI2016]神秘数(主席树,dp)
    洛谷 P2894 [USACO08FEB]Hotel G(线段树)
    洛谷 P2414 [NOI2011] 阿狸的打字机(AC自动机、树状数组)
    洛谷 P2829 大逃离(最短路)
    洛谷 P2292 [HNOI2004]L语言(AC自动机,dp)
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998370.html
Copyright © 2020-2023  润新知