Shortest Path
Time Limit:2000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I64u
Submit
Status
Practice
HDU 5636
Description
There is a path graph
G=(V,E)
with
n
vertices. Vertices are numbered from
You are given the graph and several queries about the shortest path between some pairs of vertices.
Input
There are multiple test cases. The first line of input contains an integer
The first line contains two integer
n
and
In the next
m
lines, each contains two integers
The sum of values of
m
in all test cases doesn’t exceed
Output
For each test cases, output an integer
S=(∑i=1mi⋅zi) mod (109+7)
, where
zi
is the answer for
i
<script type="math/tex" id="MathJax-Element-3822">i</script>-th query.
Sample Input
1
10 2
2 4 5 7 8 10
1 5
3 1
Sample Output
7
题意:给你1—>n个点,每两个点距离是 1,再添加三条路,每条路的距离是1,求所给的式子
用floyd算法,我也是没有想过的,看了别人的题解才懂, 题目给的三条路的六个点,可以用floyd算法求这六个点之间的最短路,为什么呢?因为要求问的两个点之间的距离,那么这两个点之间的最小距离要么是它们的直接距离,要么就是过这六个点的两个,在用floyd算法就可以直接求出最短的了
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
#define M 7
LL dist[M][M];
int a[M];
int abs(int a)
{
return a < 0 ? (-a) : a;
}
void floyd()
{
for(int k=1; k<M; k++)
{
for(int i=1; i<M; i++)
{
for(int j=1; j<M; j++)
{
dist[i][j] = dist[j][i] = min(dist[i][j], dist[i][k] + dist[k][j]);
}
}
}
}
int main()
{
int t, n, m;
LL mod = 1e9+7;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &m);
for(int i=1; i<=6; i++)
{
scanf("%d", &a[i]);
}
for(int i=1; i<M; i++)//离散化一下使得 i, j直接表示 ai,aj
{
for(int j=1; j<M; j++)
{
dist[i][j] = abs(a[i] - a[j]);
}
}
dist[1][2] = dist[2][1] = 1;//缩短距离
dist[3][4] = dist[4][3] = 1;
dist[5][6] = dist[6][5] = 1;
floyd();//求六个点之间的最短距离
LL ans = 0, flag = 0;
int x, y;
for(int i=1; i<=m; i++)
{
flag = 0;
scanf("%d%d", &x, &y);
flag = abs(x - y);
for(int j=1; j<M; j++)
{
for(int k=1; k<M; k++)
{
flag = min(flag, abs(x - a[k]) + abs(y - a[j]) + dist[k][j]);//计算最短距离
flag = min(flag, abs(y - a[k]) + abs(x - a[j]) + dist[k][j]);
}
}
ans += (flag * i) % mod;
ans %= mod;
}
printf("%lld\n", ans);
}
return 0;
}