HDU-5636(Shortest Path)(floyd最短路径)
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1393 Accepted Submission(s): 440
You are given the graph and several queries about the shortest path between some pairs of vertices.
The first line contains two integer n and m(1≤n,m≤105) -- the number of vertices and the number of queries. The next line contains 6 integersa1,b1,a2,b2,a3,b3(1≤a1,a2,a3,b1,b2,b3≤n), separated by a space, denoting the new added three edges are (a1,b1),(a2,b2),(a3,b3).
In the next m lines, each contains two integers si and ti(1≤si,ti≤n), denoting a query.
The sum of values of m in all test cases doesn't exceed 106.
特殊处理+floyd。
可以把基本情况看做:h x[i] x[j] l ,其中h与l是待求的两点,x[i]、x[j],是6个点中的任意两个点。在求待求两点之间的最短路径时,可以把整条路径看做3段。 (1)h 到 x[i] (2)x[i]到 x[j] (3) x[j] 到 l 。通过遍历所有情况来获取最短的路径。因为这六个点之间因为3座桥,而使路径变短。所以在从h到i的路径中,有桥,则可以使路径变短。
当情况为:h l x[i] x[j]或x[i] x[j] l h时,最短路径s,则为:s=abs(h-l);
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
{
ans=min(ans,abs(h-x[i])+m1[i][j]+abs(l-x[j])) ;
//h与l,x[i]与x[j]的前后关系不能确定,所以需要把h与l的位置互换来确定最小值
ans=min(ans,abs(l-x[i])+m1[i][j]+abs(h-x[j])) ;
}
My solution:
/*2016.3.17*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define mod 1000000007
long long m1[7][7];
long long ans;
int x[7],n,m;
void floyd()//更新6个点之间的最短距离
{
int i,j,k;
for(k=1;k<=6;k++)
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
{
if(m1[i][j]>(m1[i][k]+m1[k][j]))
m1[i][j]=m1[i][k]+m1[k][j];
}
return ;
}
int main()
{
int i,j,k,h,l,p,t;
long long sum,q;
scanf("%d",&t);
while(t--)
{
q=1;
sum=0;
scanf("%d%d",&n,&m);
for(i=1;i<=6;i++)
{
scanf("%d",&x[i]);
}
for(i=1;i<=6;i++)
{
for(j=1;j<=6;j++)
{
m1[i][j]=m1[j][i]=abs(x[i]-x[j]);//暂存6个点之间的距离
}
}
m1[1][2]=m1[2][1]=q;//把3座桥对应的顶点之间的距离填充到最短路径上
m1[3][4]=m1[4][3]=q;//无向图
m1[5][6]=m1[6][5]=q;
floyd();//更新6个点之间的最短路
for(k=1;k<=m;k++)
{
scanf("%d%d",&h,&l);
ans=abs(h-l);//待测路径的初始值
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
{
ans=min(ans,abs(h-x[i])+m1[i][j]+abs(l-x[j])) ; //h与l,x[i]与x[j]的前后关系不能确定,所以需要把h与l的位置互换来确定最小值
ans=min(ans,abs(l-x[i])+m1[i][j]+abs(h-x[j])) ;
}
ans=(ans*k)%mod;
sum=(sum+ans)%mod;
}
sum%=mod;
printf("%I64d\n",sum);
}
return 0;
}