• 计蒜客-百度地图导航


    题意:中文题意;

    解题思路:这道题麻烦就在于城市群这个东西,所以我们首先就得解决掉这个,最开始思路(建立虚拟源点和汇点,然后有1的城市群和有5的城市群分别连,然后就发现了连样例都对不上,正好发现了如果s,t在同一群内,会造成城市群内的点任意到达这种情况),明显需要拆点,将一个城市群拆成两个点,一个入点,一个出点,如果两个城市群之间有路径,那么x出连接y入,y出连接x入,城市群内的点分别与出点连接权值为0的边,入点分别与群内的点连接一个边权为0的边;

    实际上就是我们对城市群处理一下,因为暴力建边不行,我们只能想办法将两个城市群连接起来,那么建立每个城市群建立两个虚拟的城市群源汇点就行了;这样,通过这两个点可以让两个城市群相连。

    记得long long 和无解的情况;

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define maxn 1000500
    #define ll long long
    const ll inf=1e15;
    using namespace std;
    struct node
    {
        ll num;
        ll dist;
        node(ll _num=0,ll _dist=0):num(_num),dist(_dist){}
        friend bool operator<(node a,node b)
        {
            return a.dist>b.dist;
        }
    };
    struct Edge
    {
        ll next;
        ll to;
        ll w;
    }edge[maxn];
    ll n,m,k,m1,m2,x,y,w,q;
    ll s,t;
    ll head[maxn];
    ll cnt;
    ll dist[maxn];
    void add(ll u,ll v,ll w)
    {
        edge[cnt].next=head[u];
        edge[cnt].to=v;
        edge[cnt].w=w;
        head[u]=cnt++;
    }
    void dij(ll u)
    {
        for(ll i=1;i<=maxn;i++)
            dist[i]=inf;
        dist[u]=0;
        priority_queue<node>q;
        q.push(node(u,dist[u]));
        while(!q.empty())
        {
            node now=q.top();q.pop();
            ll x=now.num;
            for(ll i=head[x];i!=-1;i=edge[i].next)
            {
                ll v=edge[i].to;
                if(dist[v]>dist[x]+edge[i].w)
                {
                    dist[v]=dist[x]+edge[i].w;
                    q.push(node(v,dist[v]));
                }
            }
        }
    }
    int main()
    {
    
        scanf("%lld%lld",&n,&m);memset(head,-1,sizeof(head));cnt=0;
        for(ll i=1;i<=m;i++)
        {
            scanf("%lld",&k);
            for(ll j=1;j<=k;j++)
            {
                scanf("%lld",&q);
                add(n+i,q,0);
                add(q,n+n+i,0);
            }
        }
        scanf("%lld",&m1);
        for(ll i=1;i<=m1;i++)
        {
            scanf("%lld%lld%lld",&x,&y,&w);
            add(x,y,w);add(y,x,w);
        }
        scanf("%lld",&m2);
        for(ll i=1;i<=m2;i++)
        {
            scanf("%lld%lld%lld",&x,&y,&w);
            add(n+n+x,n+y,w);
            add(n+n+y,n+x,w);
        }
        scanf("%lld%lld",&s,&t);
        dij(s);
        if(dist[t]==inf)
            printf("-1
    ");
        else
        printf("%lld
    ",dist[t]);
    }
    

      

  • 相关阅读:
    ros之MarkerArray使用
    boost之进度条工具
    opencv之对比度和亮度的调节
    opencv之通道分离和合并
    opencv之图像叠加与图像混合
    opencv之绘制基本图形
    opencv之几种常用的类型
    opencv之cv::Mat创建
    ros之自定义message
    opencv与eigen类型转换
  • 原文地址:https://www.cnblogs.com/huangdao/p/9530704.html
Copyright © 2020-2023  润新知