bestcoder round 74 div1

Shortest Path

 
 Accepts: 80
 
 Submissions: 431
 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
solution:这里唯一的干扰元素只有新增的边,所以我直接枚举用了几条边,对边进行全排列即可。
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<cmath>
#define ll long long
const int mod=1000000007;
int t,n,m,x,y,dis;
int p[5],a[5],b[5];
int son[100005];
ll ans;
int abs(int a)
{
    if(a<0) return -a;else return a;
}
int mi(int a,int b)
{
    if(a<b) return a; else return b;
}
void dfs(int k,int now,int s,int all)
{
    if(now>all)
    {
        dis=mi(dis,s+abs(k-y));
        return;
    }
    for(int i=1;i<=3;i++)
    if(p[i]==0)
    {
        p[i]=1;
        dfs(b[i],now+1,s+abs(k-a[i])+1,all);
        dfs(a[i],now+1,s+abs(k-b[i])+1,all);
        p[i]=0;
    }
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=3;i++) scanf("%d%d",&a[i],&b[i]);
        ans=0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            dis=abs(x-y);
            for(int j=1;j<=3;j++) dfs(x,1,0,j);
            ans=(ans+((ll)(i)*(ll)(dis))%mod)%mod;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}










你可能感兴趣的:(bestcoder round 74 div1)