zoukankan      html  css  js  c++  java
  • 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;
     } 
  • 相关阅读:
    开发中的问题
    页面重定向Redirect时产生错误
    项目管理的几个阶段及分工
    让你的CSS像Jquery一样做筛选
    项目中的几个SQL程序
    SharePoint2010人员搜索配置心得
    TroubleShoot:该搜索请求无法连接到搜索服务
    转:软件架构师应该知道的97件事
    通用动态生成静态HTML页方法
    简单的正则表达式过滤网址
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7400098.html
Copyright © 2011-2022 走看看