Shortest Path

Shortest Path

 
 Accepts: 40
 
 Submissions: 610
 Time Limit: 4000/2000 MS (Java/Others)
 
 Memory Limit: 131072/131072 K (Java/Others)
问题描述
有一条长度为nn的链. 节点iii+1i+1之间有长度为11的边. 现在又新加了3条边, 每条边长度都是1. 给出mm个询问, 每次询问两点之间的最短路.
输入描述
输入包含多组数据. 第一行有一个整数TT, 表示测试数据的组数. 对于每组数据:

第一行包含2个整数nnmm (1 \le n,m \le 10^5)(1n,m105)表示节点的数目和询问数目. 接下来一行包含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)(1a1,a2,a3,b1,b2,b3n), 表示新加的三条边为(a_1,b_1)(a1,b1), (a_2,b_2)(a2,b2), (a_3,b_3)(a3,b3). 接下来mm行, 每行包含两个整数s_isit_iti (1 \le s_i, t_i \le n)(1si,tin), 表示一组询问.

所有数据中mm的和不超过10^6106.
输出描述
对于每组数据, 输出一个整数S=(\displaystyle\sum_{i=1}^{m} i \cdot z_i) \text{ mod } (10^9 + 7)S=(i=1mizi) mod (109+7), 其中z_izi表示第ii组询问的答案.
输入样例
1
10 2
2 4 5 7 8 10
1 5
3 1
输出样例
7


这道题刚开始想要建立一个二维的dis来装下所有点到所有点之间的距离,但是最后发现直接都不能编译,太大了。。。。。。。。

所以看了比赛完后的解题思路以及其他人的代码,才明白了原来可以只存下改变的6个点之间任意两点间的距离

#include <iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define mm 1000000007
#define ll long long
int dis[10][10];
int main()
{
    int t,n,m,x,y;
    int a[10];
    scanf("%d",&t);
    while(t--)
    {
        long long ans=0;
        int dist;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=6;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=6;i++)
            for(int j=1;j<=6;j++)
        {
            dis[i][j]=dis[j][i]=abs(a[i]-a[j]);
        }
        for(int i=1;i<=6;i+=2)
            dis[i][i+1]=dis[i+1][i]=1;
        for(int k=1;k<=6;k++)
        for(int i=1;i<=6;i++)
            for(int j=1;j<=6;j++)
        {
            dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
        }
        for(int k=1;k<=m;k++)
        {
            scanf("%d%d",&x,&y);
            dist=abs(x-y);
            for(int i=1;i<=6;i++)
                for(int j=1;j<=6;j++)
            {
                dist=min(dist,abs(x-a[i])+dis[i][j]+abs(y-a[j]));
            }
            ans+=(ll)k*dist;               //ll很必要
            ans%=mm;
        }
        printf("%I64d\n",ans%mm);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值