hdu2066
其实非常没有必要像刚刚那样,可能是没有真正理解dij吧。 事实上,对每个起点调用dij算法后,每个终点的最短路长度都已经出来了。
对于每个起点,从这些终点的最短路中选出最最短路就可以了。 然后在比较每个终点,即求得最小值。
照这个思想敲了个代码一交,781ms,才快了110ms。 不应该啊~
然后比较了一下网上的代码,发现我没有剪枝。
加上条件 if(min==inf) break; // 剩余的点距离都为无穷远时,结束
再一交,78ms。好爽,终于ok了。
AC:
#include<stdio.h>
#include<string.h>
#define inf 100000000
int map[1200][1200];
int d[1200];
int s[1200];
int from[1200];
int want[1200];
int t,ss,dd; // ss 个起点 dd个终点
int dij(int v)
{
int i,j,min,pos;
for(i=1;i<=1050;i++)
{
s[i]=0;
d[i]=map[v][i];
}
s[v]=1;
d[v]=0;
for(i=1;i<1050;i++)
{
min=inf;
for(j=1;j<=1050;j++)
{
if(!s[j]&&min>d[j])
{
pos=j;
min=d[j];
}
}
s[pos]=1;
if(min==inf) break; //当剩余点距离都为无限大,结束
for(j=1;j<=1050;j++)
{
if(!s[j]&&d[j]>(d[pos]+map[pos][j]))
d[j]=d[pos]+map[pos][j];
}
}
min=inf;
for(i=1;i<=dd;i++)
{
if(min>d[want[i]])
min=d[want[i]];
}
return min;
}
int main()
{
int i,j,k;
int a,b,time;
while(scanf("%d%d%d",&t,&ss,&dd)!=EOF)
{
for(i=1;i<=1100;i++)
for(j=1;j<=1100;j++)
map[i][j]=inf;
for(i=1;i<=t;i++)
{
scanf("%d%d%d",&a,&b,&time);
if(map[a][b]>time)
map[a][b]=map[b][a]=time;
}
for(i=1;i<=ss;i++)
scanf("%d",&from[i]);
for(i=1;i<=dd;i++)
scanf("%d",&want[i]);
k=inf;
for(i=1;i<=ss;i++)
{
if(k>dij(from[i]))
k=dij(from[i]);
}
printf("%d\n",k);
}
return 0;
}