您的位置:首页 > 其它

Shortest Path(hdu5636)

2016-03-07 09:29 239 查看

ShortestPath

Accepts:40

Submissions:610

TimeLimit:4000/2000MS(Java/Others)

MemoryLimit:131072/131072K(Java/Others)

问题描述
有一条长度为nn的链.节点ii和i+1i+1之间有长度为11的边.现在又新加了3条边,每条边长度都是1.给出mm个询问,每次询问两点之间的最短路.

输入描述
输入包含多组数据.第一行有一个整数TT,表示测试数据的组数.对于每组数据:

第一行包含2个整数nn和mm(1\len,m\le10^5)(1≤n,m≤10​5​​)表示节点的数目和询问数目.接下来一行包含66个有空格分开的整数a_1,b_1,a_2,b_2,a_3,b_3a​1​​,b​1​​,a​2​​,b​2​​,a​3​​,b​3​​(1\lea_1,a_2,a_3,b_1,b_2,b_3\len)(1≤a​1​​,a​2​​,a​3​​,b​1​​,b​2​​,b​3​​≤n),表示新加的三条边为(a_1,b_1)(a​1​​,b​1​​),(a_2,b_2)(a​2​​,b​2​​),(a_3,b_3)(a​3​​,b​3​​).接下来mm行,每行包含两个整数s_is​i​​和t_it​i​​(1\les_i,t_i\len)(1≤s​i​​,t​i​​≤n),表示一组询问.

所有数据中mm的和不超过10^610​6​​.

输出描述
对于每组数据,输出一个整数S=(\displaystyle\sum_{i=1}^{m}i\cdotz_i)\text{mod}(10^9+7)S=(​i=1​∑​m​​i⋅z​i​​)mod(10​9​​+7),其中z_iz​i​​表示第ii组询问的答案.

输入样例
1
102
2457810
15
31

输出样例
7
思路:因为在每加入这些边之前我们知道任意两点最短距离是abs(a-b);
那么我们每次要询问两个点之间的最短路,所以我们可以把新加的边和询问的边中两个点拿出来离散化下
然后建图加边,然后直接最短路即可,复杂度为O(m*8*8)。


#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<map>
usingnamespacestd;
typedeflonglongLL;
intflag[10];
constLLN=1e9+7;
intcmp(constvoid*p,constvoid*q);
typedefstructpp
{
LLx;
intid;
}ss;
ssaa[10];
LLd[10];LLma[10][10];
LLnum[10];LLbum[10];
voiddij(intn,intans);
intmain(void)
{
LLi,j,k,p,q;
scanf("%lld",&k);
while(k--)
{
scanf("%lld%lld",&p,&q);
for(i=0;i<6;i++)
{
scanf("%lld",&num[i]);
}LLsum=0;LLa=0;
while(q--)
{a++;
scanf("%lld%lld",&num[6],&num[7]);
LLans=1;
for(i=0;i<8;i++)
{
aa[i].x=num[i];
aa[i].id=i;
}qsort(aa,8,sizeof(ss),cmp);
bum[aa[0].id]=1;
for(i=1;i<8;i++)
{
if(aa[i].x!=aa[i-1].x)
ans++;
bum[aa[i].id]=ans;
}
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
ma[i][j]=N;
}
}
ma[bum[0]][bum[1]]=ma[bum[1]][bum[0]]=1;
ma[bum[2]][bum[3]]=ma[bum[3]][bum[2]]=1;
ma[bum[4]][bum[5]]=ma[bum[5]][bum[4]]=1;
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
LLx=bum[i];
LLy=bum[j];
ma[x][y]=min(ma[x][y],abs(num[i]-num[j]));
}
}
dij(bum[6],ans);sum=(sum%N+d[bum[7]]*a%N)%N;
}printf("%lld\n",sum);
}return0;
}

voiddij(intn,intans)
{
fill(d,d+10,N);
memset(flag,0,sizeof(flag));
d
=0;inti,j;
while(true)
{
intl=-1;
for(i=1;i<=ans;i++)
{
if((l==-1||d[l]>d[i])&&!flag[i])
{
l=i;
}
}if(l==-1)
break;
flag[l]=1;
for(i=1;i<=ans;i++)
{
d[i]=min(ma[l][i]+d[l],d[i]);
}
}
}
intcmp(constvoid*p,constvoid*q)
{
ss*n=(ss*)p;
ss*m=(ss*)q;
returnn->x>m->x?1:-1;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: