• 2017计蒜之道复赛 百度地图导航


    分析:这道题本质就是很简单的最短路问题,但是如果连边用O(n^2)的暴力会直接TLE掉,连一条边的复杂度是减少不了了,那么能不能减少连边的数量呢?

    我们可以设置一个中间点p,假设a中的所有点要到b中去,则从a向p连一条有向边,p向b连一条有向边,可是这样权值不好办啊,那么我们把每个城市圈当作一个中心点,这样从a连向a',a'连向b',b'连向b,除了中间这条边以外的边权值都是0,但是我也有可能从b走向a啊,那么a到a'的两条边的边权都是0,这样会陷入死循环啊?

          解决方法很简单,我们把每个中心点拆成两个点,一个点只能进来,一个点只能出去,中心点之间的连边都从出去的点连向进来的点,跑一下最短路就好了.注意要用到long long!

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    const long long inf = 1e15;
    
    int n,m,m1,m2,s,t,head[100010],to[200010],nextt[200010],w[200010],tot,vis[100010];
    long long d[100010];
    
    void add(int x,int y,int z)
    {
        w[tot] = z;
        to[tot] = y;
        nextt[tot] = head[x];
        head[x] = tot++;
    }
    
    void spfa()
    {
        for (int i = 1; i <= n + m + m; i++)
        d[i] = inf;
        queue <int> q;
        q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for (int i = head[u]; i + 1; i = nextt[i])
            {
                int v = to[i];
                if (d[v] > d[u] + w[i])
                {
                    d[v] = d[u] + w[i];
                    if (!vis[v])
                    {
                        vis[v] = 1;
                        q.push(v);
                    }
                }
            }
        }
    }
    
    int main()
    {
        memset(head,-1,sizeof(head));
        scanf("%d%d",&n,&m);
        for (int i = 1; i <= m; i++)
        {
            int k;
            scanf("%d",&k);
            for (int j = 1; j <= k; j++)
            {
                int t;
                scanf("%d",&t);
                add(t,i + n,0);
                add(i + n + m,t,0);
            }
        }
        scanf("%d",&m1);
        for (int i = 1; i <= m1; i++)
        {
            int u,v,c;
            scanf("%d%d%d",&u,&v,&c);
            add(u,v,c);
            add(v,u,c);
        }
        scanf("%d",&m2);
        for (int i = 1; i <= m2; i++)
        {
            int a,b,l;
            scanf("%d%d%d",&a,&b,&l);
            add(a + n,b + n + m,l);
            add(b + n,a + n + m,l);
        }
        scanf("%d%d",&s,&t);
        spfa();
        if (d[t] == inf)
        printf("-1
    ");
        else
        printf("%lld
    ",d[t]);
        
        return 0;
     } 
  • 相关阅读:
    行为型模式续(中介者模式 + 解释器模式)
    行为型模式下<迭代器模式、访问者模式、备忘录模式>
    行为型模式中<职责链模式、状态模式、观察者模式>
    下载vuejs,Hello Vue(vscode)
    node.js运行配置(vs code非控制台输出)
    node.js环境配置(windows系统)
    玩转visual studio系列之类设计图
    xml基础之二(XML结构【2】)DTD文档模版
    xml基础之二(XML结构【1】)
    XML的基础之一(概念和语法)
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7400098.html
Copyright © 2020-2023  润新知