2017 计蒜之道 百度地图导航(缩点+最短路)
来源:互联网 发布:淘宝 主营 在哪里填写 编辑:程序博客网 时间:2024/05/24 07:18
百度地图上有 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 42 5 12 2 41 32 3 421 2 91 5 1821 2 61 3 101 5
样例输出
12
题解:
把每个城市群抽象成两个点 s′,s′′。
对于每个城市群里面的城市 si,连边:(si,s′,0), (s′′,si,0);
第一种边正常连边:(u,v,c),(v,u,c);
第二种边连边:(a′,b′′,l), (b′,a′′,l)。
然后跑一遍 s−t 最短路就是答案。
#include<iostream>#include<cstring>#include<cstdio>#include<vector>#include<queue>using namespace std;typedef long long ll;const int maxn = 400005;const ll INF = 1e18;int head[maxn], cnt, n, m;ll dis[maxn];bool vis[maxn];struct Edge{ int v, nxt; ll w;}edge[maxn];struct node{ int point; ll distance; node(int _point, ll _distance) {point = _point; distance = _distance;} bool operator < (const node &other)const { return distance > other.distance; }};void Addedge(int u, int v, ll w){ edge[cnt].v = v; edge[cnt].w = w; edge[cnt].nxt = head[u]; head[u] = cnt++;}void Dijkstra(int s){ for(int i = 1; i <= n; i++) dis[i] = INF; memset(vis, false, sizeof(vis)); dis[s] = 0; priority_queue<node> q; q.push(node(s, dis[s])); while(!q.empty()) { node now = q.top(); q.pop(); if(vis[now.point]) continue; vis[now.point] = true; for(int i = head[now.point]; i != -1; i = edge[i].nxt) { int to = edge[i].v; if(dis[to] > dis[now.point] + edge[i].w) { dis[to] = dis[now.point] + edge[i].w; q.push(node(to, dis[to])); } } }}int main(){ ll w; int k, u, v, m1, m2; while(scanf("%d%d", &n, &m) != EOF) { cnt = 0; memset(head, -1, sizeof(head)); for(int i = 1; i <= m; i++) { scanf("%d", &k); while(k--) { scanf("%d", &u); Addedge(u, n+i, 0); Addedge(n+m+i, u, 0); } } scanf("%d", &m1); while(m1--) { scanf("%d%d%lld", &u, &v, &w); Addedge(u, v, w); Addedge(v, u, w); } scanf("%d", &m2); while(m2--) { scanf("%d%d%lld", &u, &v, &w); Addedge(n+u, n+v+m, w); Addedge(n+v+m, n+u, w); Addedge(n+u+m, n+v, w); Addedge(n+v, n+u+m, w); } n = n + m * 2; int s, t; scanf("%d%d", &s, &t); Dijkstra(s); if(dis[t] == INF) puts("-1"); else printf("%lld\n", dis[t]); } return 0;}
- 2017 计蒜之道 百度地图导航(缩点+最短路)
- 2017 计蒜之道 复赛 百度地图导航 (拆点+最短路)
- 2017 计蒜之道 复赛 百度地图导航【思维+最短路】
- 2017计蒜之道复赛 百度地图导航 (最短路)
- [最短路] 2017 计蒜之道 复赛 D. 百度地图导航
- [最短路] 2017 计蒜之道 复赛 D. 百度地图导航
- 2017 计蒜之道 复赛 百度地图导航(拆点最短路)
- 计蒜客-2017 计蒜之道 复赛-D-百度地图导航
- [最短路]D. 百度地图导航
- 计蒜之道复赛D题—— 百度地图导航
- 2017 计蒜之道 复赛 <状压DP+最短路>
- 百度地图之导航
- 计算客复赛 D题 百度地图导航(最短路)
- 计蒜之道复赛A题 百度地图的实时路况(分治+floyd)
- 2016计蒜之道 复赛 A. 百度地图的实时路况(cdq分治+floyd)
- 算法:分治+floyd_计蒜之道复赛A题 百度地图的实时路况
- [分治 floyed] 2016 计蒜之道 复赛 百度地图的实时路况
- 2016 计蒜之道 复赛 百度地图的实时路况 [Floyd][分治]
- LeetCode1 two sum
- .net 返回前端json数据
- 用VBA编程处理数据
- Windows下配置nginx+php(wnmp)
- 行为数据的价值发现
- 2017 计蒜之道 百度地图导航(缩点+最短路)
- 数据结构:查找
- [树的点分治] [POJ1741/POJ1987] Tree/Distance Statistics
- 欢迎使用Markdown编辑器写博客
- Linux CentOS/Ubuntu java jdk安装配置 离线安装与在线安装
- 洛谷Oj-数字三角形-动态规划
- TankWar2.1(坦克相撞问题)
- windows下的DOS进入mysql数据库
- Android Studio的设置