码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-08-20 15:44:50      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:oid   log   span   ret   ++   mil   image   include   push   

技术分享

技术分享

分析:这道题本质就是很简单的最短路问题,但是如果连边用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\n");
    else
    printf("%lld\n",d[t]);
    
    return 0;
 } 

 

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

标签:oid   log   span   ret   ++   mil   image   include   push   

原文地址:http://www.cnblogs.com/zbtrs/p/7400098.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!