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