POJ2387

来源:互联网 发布:openwrt 设置无线 mac 编辑:程序博客网 时间:2024/05/24 00:18
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<math.h>
#define inf 0x3f3f3f;
using namespace std;
int n,w[1001][1001],m,a,b,qy,d[1001],t,mx,lj;
bool vis[1001][1001],q[1001];
int main()
{
    while(scanf("%d",&m)!=EOF)
      {
        
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
         {  
            d[i]=inf;  q[i]=1; vis[i][i]=0;
         }
          for(int i=1;i<=m;i++)
            {
               scanf("%d%d",&a,&b);
               if(vis[a][b]==0)
                 {
                   scanf("%d",&lj);
                   w[a][b]=lj;  w[b][a]=lj;
                 }
               else
                 {
                    scanf("%d",&lj);
                    if(lj<w[a][b])  {w[a][b]=lj; w[b][a]=lj;}
                 }
               vis[a][b]=1;
               vis[b][a]=1;
            }
          d[1]=0;  qy=1;  t=1;  q[1]=0;
          while(qy)
            {
               for(int i=1;i<=n;i++)
                 {
                     if(vis[t][i]==1)
                       {
                          if(d[i]>d[t]+w[t][i])
                            d[i]=d[t]+w[t][i];
                       }
                 }
               mx=inf;
               for(int i=1;i<=n;i++)
                 {
                     if(q[i]==1&&d[i]<mx)
                        {
                          mx=d[i];
                          t=i;
                        }
                 }
               q[t]=0;
               if(t==n)qy=0;
            }
            printf("%d\n",d[n]);         
     }    
    return 0;

}

第一个dijkstra算法的题目,从昨天晚上一直WA到今天下午,蛋疼的说。

主要错的地方是把PPT上面的压缩到S集合中的点U理解错了,理解成和prim算法中一样的U是在S集合外面到S集合最近的点。

U应该是到起点最近的那个点,即式子中的if(q[i]==1&&d[i]<mx)
                                                                              {mx=d[i];U=i;}

这样做虽然是贪心,但是PPT上面已证这样得到的结果一定是最优的,同时PPT上面还有一句话重要,就是说,每个点必定只会被从Q中弹出进入S中一次且仅有一次。

                       

原创粉丝点击