There is a path graph G=(V,E)G=(V,E) with nn vertices. Vertices are numbered from 11 to nnand there is an edge with unit length between ii and i+1i+1 (1≤i<n)(1≤i<n). To make the graph more interesting, someone adds three more edges to the graph. The length of each new edge is 11.
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 TT, indicating the number of test cases. For each test case:
The first line contains two integer nn and mm (1≤n,m≤105)(1≤n,m≤105) -- the number of vertices and the number of queries. The next line contains 6 integers a1,b1,a2,b2,a3,b3a1,b1,a2,b2,a3,b3 (1≤a1,a2,a3,b1,b2,b3≤n)(1≤a1,a2,a3,b1,b2,b3≤n), separated by a space, denoting the new added three edges are (a1,b1)(a1,b1), (a2,b2)(a2,b2), (a3,b3)(a3,b3).
In the next mm lines, each contains two integers sisi and titi (1≤si,ti≤n)(1≤si,ti≤n), denoting a query.
The sum of values of mm in all test cases doesn't exceed 106106.
Output
For each test cases, output an integer S=(∑i=1mi⋅zi) mod (109+7)S=(∑i=1mi⋅zi) mod (109+7), where zizi is the answer for ii-th query.
Sample Input
1 10 2 2 4 5 7 8 10 1 5 3 1
Sample Output
7
题意:
给定n个点,两个点间的距离为1,再给定3对点(3条边,权值为1),有每次询问,将每次的结果相加对1e9++7求模。
分析:
先通过一次flyod求出任意两点间的最短距离,然后以6个点为中心,再一次flyod找出输入的两点间的最小距离即可。
代码:(思路看懂了,懒的敲了,主要是没时间啊,继续补题-------)
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
using namespace std;
#define mod 1000000007
typedef long long int LL;
int dp[10][10];
int n,m;
long long int s;
int main()
{
int t;
scanf("%d",&t);
int a[10];
int x,y;
while(t--)
{
scanf("%d%d",&n,&m);
scanf("%d%d%d%d%d%d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6]);
memset(dp,0,sizeof(dp));
for(int i=1;i<=6;i++)
{
for(int j=1;j<=6;j++)
{
dp[i][j]=abs(a[j]-a[i]);
}
}
dp[1][2]=1;dp[3][4]=1;dp[5][6]=1;///更新一些点间的距离
dp[2][1]=1;dp[4][3]=1;dp[6][5]=1;
for(int k=1;k<=6;k++)///求出任意两点间的最小距离
{
for(int i=1;i<=6;i++)
{
for(int j=1;j<=6;j++)
{
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);
}
}
}
int res=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
int ans=abs(y-x);///因为权值都为1,序列号相减即为输入的两点间的距离
for(int i=1;i<=6;i++)
{
for(int j=1;j<=6;j++)
{
ans=min(ans,abs(x-a[i])+abs(y-a[j])+dp[i][j]);
}
}
// int num=i*ans%mod;
// res+=num;
// res%=mod;
(res+=(LL)i*ans%mod)%=mod;
}
printf("%d\n",res);
}
return 0;
}