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

posted on 2012-03-20 14:53  hrbust_09zhangyabin  阅读(1121)  评论(0编辑  收藏  举报