[最短路]D. 百度地图导航

来源:互联网 发布:商业数据分析报告 编辑:程序博客网 时间:2024/05/22 07:42

百度地图上有 nn 个城市,城市编号依次为 11 到 nn。地图中有若干个城市群,编号依次为 11 到 mm。每个城市群包含一个或多个城市;每个城市可能属于多个城市群,也可能不属于任何城市群。

地图中有两类道路。第一类道路是 城市之间的快速路,两个城市 u,vu,v 之间增加一条距离为 cc 的边;第二类道路是城市群之间的高速路,连接两个城市群 a,ba,b,通过这条高速路,城市群 aa 里的每个城市与城市群 bb 里的每个城市之间两两增加一条距离为 cc 的边。图中所有边均为无向边。

你需要计算从城市 ss 到城市 tt 的最短路。

输入格式

第一行输入 n(1 \le n \le 20000),n(1n20000), m(0 \le m \le 20000)m(0m20000),分别表示城市总数和城市群总数。

接下来一共输入 mm 行。

第 ii 行首先输入一个 k_i(1 \le k_i \le n)ki(1kin),表示第 ii 个城市群中的城市数为 k_iki。接下来输入 k_iki 个数,表示第 ii 个城市群中每个城市的编号(保证一个城市群内的城市编号不重复且合法,\sum_{i=1}^{m}k_i \le 20000i=1mki20000)。

下一行输入一个整数 m_1(0 \le m_1 \le 20000)m1(0m120000),表示有 m_1m1 条第一类道路,即 城市之间的快速路

接下来 m_1m1 行,每行输入三个整数 u_i,v_i(1 \le u_i, v_i \le n),c_i(1 \le c_i \le 10^6)ui,vi(1ui,vin),ci(1ci106),分别表示快速路连接的两个城市编号和边的距离。

下一行输入一个整数 m_2(0 \le m_2 \le 20000)m2(0m220000),表示有 m_2m2 条第二类道路,即 城市群之间的高速路

接下来 m_2m2 行,每行输入三个整数 a_i,b_i(1 \le a_i, b_i \le m),l_i(1 \le l_i \le 10^6)ai,bi(1ai,bim),li(1li106),分别表示快速路连接的两个城市群编号和边的距离。

最后一行输入 s, t(1 \le s, t \le n)s,t(1s,tn),表示起点和终点城市编号。

输出格式

输出一个整数,表示城市 ss 到城市 tt 到最短路。如果不存在路径,则输出-1

样例说明

1 -> 2 - > 5或者1 -> 4 -> 5是最短的路径,总长度为 1212

样例输入

5 42 5 12 2 41 32 3 421 2 91 5 1821 2 61 3 101 5

样例输出

12
/*我好难过啊*/
#include <bits/stdc++.h>#define INF 1e17using namespace std;typedef long long LL;const long long maxn=60010;struct node{    LL to,next,w;}e[maxn*80];LL head[maxn],cnt,vis[maxn],dis[maxn],n;void Init(){    memset(head,-1,sizeof(head));    cnt=0;}void add(LL u,LL v,LL w){    e[cnt].to=v;    e[cnt].w=w;    e[cnt].next=head[u];    head[u]=cnt++;}void spfa(LL x){    memset(vis,0,sizeof(vis));    for(LL i=1;i<=n*3;i++)        dis[i]=INF;    vis[x]=1;    dis[x]=0;    queue<LL>q;    q.push(x);    while(!q.empty()){        LL u=q.front();q.pop();        vis[u]=0;        for(LL i=head[u];~i;i=e[i].next){            LL v=e[i].to,w=e[i].w;            if(dis[v]>dis[u]+w){                dis[v]=dis[u]+w;                if(!vis[v]){                    vis[v]=1;                    q.push(v);                }            }        }    }}int main(){    LL m,x,u,v,w,m1,m2,k,s,t;    Init();    scanf("%lld%lld",&n,&m);    for(LL i=1;i<=m;i++){/*拆点*/        scanf("%lld",&k);        while(k--){            scanf("%lld",&x);            add(x,n+i,0);            add(n+i+n,x,0);        }    }    scanf("%lld",&m1);    while(m1--){        scanf("%lld%lld%lld",&u,&v,&w);        add(u,v,w);        add(v,u,w);    }    scanf("%lld",&m2);    while(m2--){        scanf("%lld%lld%lld",&u,&v,&w);        add(u+n,v+n+n,w);        add(v+n,u+n+n,w);    }    scanf("%lld%lld",&s,&t);    spfa(s);    if(dis[t]==INF)        printf("-1\n");    else printf("%lld\n",dis[t]);}/*5 23 1 2 32 4 511 2 511 2 11 2*/

原创粉丝点击