HDU 5636:Shortest Path floyd
2016-03-06 20:14
316 查看
Shortest Path
Accepts: 80Submissions: 431
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 131072/131072 K (Java/Others)
问题描述
有一条长度为nn的链. 节点ii和i+1i+1之间有长度为11的边. 现在又新加了3条边, 每条边长度都是1. 给出mm个询问, 每次询问两点之间的最短路.
输入描述
输入包含多组数据. 第一行有一个整数TT, 表示测试数据的组数. 对于每组数据: 第一行包含2个整数nn和mm (1 \le n,m \le 10^5)(1≤n,m≤105)表示节点的数目和询问数目. 接下来一行包含66个有空格分开的整数a_1, b_1, a_2, b_2, a_3, b_3a1,b1,a2,b2,a3,b3 (1 \le a_1,a_2,a_3,b_1,b_2,b_3 \le n)(1≤a1,a2,a3,b1,b2,b3≤n), 表示新加的三条边为(a_1,b_1)(a1,b1), (a_2,b_2)(a2,b2), (a_3,b_3)(a3,b3). 接下来mm行, 每行包含两个整数s_isi和t_iti (1 \le s_i, t_i \le n)(1≤si,ti≤n), 表示一组询问. 所有数据中mm的和不超过10^6106.
输出描述
对于每组数据, 输出一个整数S=(\displaystyle\sum_{i=1}^{m} i \cdot z_i) \text{ mod } (10^9 + 7)S=(i=1∑mi⋅zi) mod (109+7), 其中z_izi表示第ii组询问的答案.
输入样例
1 10 2 2 4 5 7 8 10 1 5 3 1
输出样例
7
添加三条边,然后再“硬算”,要考虑很多种情况。
对添加的6个点floyd算出最短距离,然后对每对u,v,枚举中间的两个点。
代码:
#pragma warning(disable:4996) #include <iostream> #include <functional> #include <algorithm> #include <cstring> #include <vector> #include <string> #include <cstdio> #include <cmath> #include <queue> #include <stack> #include <deque> #include <set> #include <map> using namespace std; typedef long long ll; #define INF 0x3fffffffffffffff const ll mod = 1e9 + 7; const int maxn = 1e5 + 5; int n, m; int a[10], b[10]; int dis[10][10]; int getpos(int x) { return lower_bound(a + 1, a + 6 + 1, x) - a; } void solve() { int i, j, k; int x1, x2, u, v; scanf("%d%d", &n, &m); for (i = 1; i <= 6; i++) { scanf("%d", &a[i]); b[i] = a[i]; } sort(a + 1, a + 6 + 1); for (i = 1; i <= 6; i++) { for (j = 1; j <= 6; j++) { dis[i][j] = abs(a[i] - a[j]); } } x1 = getpos(b[1]); x2 = getpos(b[2]); dis[x1][x2] = dis[x2][x1] = min(dis[x1][x2], 1); x1 = getpos(b[3]); x2 = getpos(b[4]); dis[x1][x2] = dis[x2][x1] = min(dis[x1][x2], 1); x1 = getpos(b[5]); x2 = getpos(b[6]); dis[x1][x2] = dis[x2][x1] = min(dis[x1][x2], 1); //做的时候没有注意到这里。。。 for (k = 1; k <= 6; k++) { for (i = 1; i <= 6; i++) { for (j = 1; j <= 6; j++) { dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); } } } ll ans = 0; for (k = 1; k <= m; k++) { scanf("%d%d", &u, &v); ll res = abs(u - v); for (i = 1; i <= 6; i++) { for (j = 1; j <= 6; j++) { res = min(res, (ll)(abs(u - a[i]) + abs(v - a[j]) + dis[i][j])); } } ans = (ans + (ll)(res*k)%mod) % mod; } printf("%lld\n", ans); } int main() { #ifndef ONLINE_JUDGE freopen("i.txt", "r", stdin); freopen("o.txt", "w", stdout); #endif int t; scanf("%d", &t); while (t--) { solve(); } return 0; }
相关文章推荐
- Swift泛型
- SpringMVC 基于注解的Controller @RequestMapping @Request
- 面包屑导航
- BigPipe——流水线式的动态并行处理
- 浅析设计模式之观察者模式
- C语言模仿C#事件
- Android Volley完全解析(二),使用Volley加载网络图片
- nyoj42 一笔画问题
- 学生的自我修养
- pat 1067 Sort with Swap(0,*) (25)
- python下spark_RDD认识与操作
- ClassLoader:类加载详解
- 怎样使用指定的字符集创造String对象
- ZooKeeper 笔记(2) 监听数据变化
- 网页打不开,但是可以登录QQ,Win10
- 提高生产力的6个Visual Studio技巧
- MYSQL:ERROR 1148: The used command is not allowed with this MySQL version
- 第二天 XML SD卡 SharedPreferences
- bzoj2286 消耗战 虚树&树形dp
- Android学习笔记(一)