HDU 5636 Shortest Path(Floyed,枚举)

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;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会敲代码的小帅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值