UVa OJ 10801

1、不知道是UVa的题太难了还是我太弱了,这道题写了三个多小时。终于学会了用优先队列来优化的dijkstra以及前向星表示法。

2、我是这么做的:对每一对结点(楼层),记录四个信息,始发点,终点,时间,电梯类型。注意每一对都要,而不是仅仅是楼层相连的需要。否则在加60的时候会遇到麻烦,dijkstra说到底是用的贪心,如果仅仅记录相连的楼层的话,可能会漏掉一些方案(目光短浅)。我举个例子,如0到1楼是乘坐1号电梯,1到2楼用1号电梯花费是10,2到3楼用1号花费是1000,1到2楼用2号电梯花费是1,2到3楼用2号花费是1,这样在做最初的决策的时候,由于从1到2楼如果换乘2号电梯的话,会额外花费60的费用,所以这条路就不可能再走了,但是它看不到2到3楼有1000的花费在等着。所以说贪心是短视的。

3、后来还是一直过不了第二个样例,我才发现是数组开小了,前向星表示法,first数组记录第一个边的编号,它的元素个数等于结点数,next数组记录某个边的下一个边的编号,它的元素个数等于边的数目。

4、交上去一次AC,还是挺值得高兴的。

int a[100];
int n,k,cnt;
priority_queue<point,vector<point>,cmp>q;
void init(){
 for(int i=0;i<n;i++)
   scanf("%d",&cost[i]);
        for(int i=0;i<MAXN;i++)
   d[i]=(i==0?0:INF);
 for(int i=0;i<n;i++){    
  int temp,N=0;
  char ch;
     while(scanf("%d",&temp)==1){
   a[N++]=temp;
            if((ch=getchar())=='\n') break;
  }
  for(int j=0;j<N-1;j++){
   for(int h=j+1;h<N;h++){
    int num=abs(a[h]-a[j])*cost[i];
    e[cnt].u=a[j];e[cnt].v=a[h];e[cnt].w=num;e[cnt].type=i;    
             e[cnt+1].u=a[h];e[cnt+1].v=a[j];e[cnt+1].w=num;e[cnt+1].type=i;
             cnt+=2;
   }
  }
 }
 return;
}
int main(){
 //freopen("lift.in","r",stdin);
 //freopen("lift.out","w",stdout);
 while(scanf("%d%d",&n,&k)==2){
  cnt=0;
  init();
  for(int i=0;i<MAXN;i++) first[i]=-1;
  for(int j=0;j<cnt;j++){
      next[j]=first[e[j].u];
   first[e[j].u]=j;
  }
        memset(done,0,sizeof(done));
  q.push(point(d[0],0,-1));
  while(!q.empty()){
      point u=q.top();q.pop();
   int x=u.num;
   if(done[x]) continue;
   done[x]=true;
   int plus;
   for(int i=first[x];i!=-1;i=next[i]){
    if(e[i].type==u.type||u.type==-1) plus=0;
    else plus=60;
              if(d[e[i].v]>d[x]+e[i].w+plus){
        d[e[i].v]=d[x]+e[i].w+plus;
     q.push(point(d[e[i].v],e[i].v,e[i].type));
    }
   }
  }
  if(d[k]!=INF)
           printf("%d\n",d[k]);
  else printf("IMPOSSIBLE\n");
 }
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值