百度地图上有 n 个城市,城市编号依次为 1 到 n。地图中有若干个城市群,编号依次为 1 到 m。每个城市群包含一个或多个城市;每个城市可能属于多个城市群,也可能不属于任何城市群。
地图中有两类道路。第一类道路是 城市之间的快速路,两个城市 u,v 之间增加一条距离为 c 的边;第二类道路是城市群之间的高速路,连接两个城市群 a,b,通过这条高速路,城市群 a 里的每个城市与城市群 b 里的每个城市之间两两增加一条距离为 c 的边。图中所有边均为无向边。
你需要计算从城市 s 到城市 t 的最短路。
输入格式
第一行输入 n(1≤n≤20000), m(0≤m≤20000),分别表示城市总数和城市群总数。
接下来一共输入 m 行。
第 i 行首先输入一个 ki(1≤ki≤n),表示第 i 个城市群中的城市数为 ki。接下来输入 ki 个数,表示第 i 个城市群中每个城市的编号(保证一个城市群内的城市编号不重复且合法,∑i=1mki≤20000)。
下一行输入一个整数 m1(0≤m1≤20000),表示有 m1 条第一类道路,即 城市之间的快速路。
接下来 m1 行,每行输入三个整数 ui,vi(1≤ui,vi≤n),ci(1≤ci≤106),分别表示快速路连接的两个城市编号和边的距离。
下一行输入一个整数 m2(0≤m2≤20000),表示有 m2 条第二类道路,即 城市群之间的高速路。
接下来 m2 行,每行输入三个整数 ai,bi(1≤ai,bi≤m),li(1≤li≤106),分别表示快速路连接的两个城市群编号和边的距离。
最后一行输入 s,t(1≤s,t≤n),表示起点和终点城市编号。
输出格式
输出一个整数,表示城市 s 到城市 t 到最短路。如果不存在路径,则输出-1
。
样例说明
1 -> 2 - > 5
或者1 -> 4 -> 5
是最短的路径,总长度为 12。
样例输入
5 4 2 5 1 2 2 4 1 3 2 3 4 2 1 2 9 1 5 18 2 1 2 6 1 3 10 1 5
样例输出
12
/*我好难过啊*/
#include <bits/stdc++.h>
#define INF 1e17
using 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 2
3 1 2 3
2 4 5
1
1 2 5
1
1 2 1
1 2
*/