计蒜客-百度地图导航

题意:中文题意;

解题思路:这道题麻烦就在于城市群这个东西,所以我们首先就得解决掉这个,最开始思路(建立虚拟源点和汇点,然后有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\n");
    else
    printf("%lld\n",dist[t]);
}

  

posted @ 2018-08-24 16:37  荒岛的龟  阅读(199)  评论(0编辑  收藏  举报