poj 1125_迪杰斯特拉

题目描述:

  在无向图中进行留言散播。不定起点,边权为一次散播时间。求散播留言到全网的最小时间。

解题思路:

v次迪杰斯特拉。每一次求从v点出发消息扩散的全网的最短时间Des[v]。在一次迪杰斯特拉中,求从v点出发到其余各点的最短时间,存到数组D[]中。计算完V到其余各点的消息扩散最短时间后,选择这个v点的D[]的最大值——即扩散到最远节点花费的时间,存为Des[v]。最后再Des[v]中选择最小值,为所求。

时间复杂度为O(v3

参考代码:

#include <stdio.h>
#include <stdlib.h>
#define Infinity 1000000000
#define N 101

int G[N][N];
int Des[N];
int D[N],final[N];

main()
{
   int i,j,k,adj,min,max,tmp;
   int n, num;
  
   scanf("%d",&n);
   while(n!=0)
   {
       for(i=1;i<=n;i++)
          for(j=1;j<=n;j++)
             G[i][j] = Infinity;
       //G[][]
       for(i=1; i<=n; i++)
       {
          scanf("%d",&num);
          for(j=1;j<=num;j++)
         
             scanf("%d",&adj);
             scanf("%d",&G[i][adj]);
                       
        
       for(k=1; k<=n; k++) //做n次迪杰斯特拉,得到Des[k]: max(D[],排除自己)
       {
          //initial
          for(i=1;i<=n;i++)
          {
             D[i] = Infinity;
             final[i] = 0;
          }
          final[k] = 1;
          for(i=1;i<=n;i++)
             D[i] = G[k][i];
         
          //find D[]
          for(i=1; i<=n; i++)//选择n-1次
          {
             min = Infinity;
             tmp = 0;
             for(j=1;j<=n;j++)//每次选进一个点
                if(!final[j])
                   if(min > D[j])
                   {
                      tmp = j;
                      min = D[j];
                   }
             if(tmp!=0)
             {
                 final[tmp] = 1;
                 //更新
                 for(j=1;j<=n;j++)
                     if(!final[j] && min+G[tmp][j] < D[j])
                        D[j] = min + G[tmp][j];
             }
          }
          max = 0;
          for(i=1; i<=n; i++)
             if(i!=k)
                if(max < D[i])
                   max = D[i];
          Des[k] = max;
       }
       //选择Des[]中最短的
       min = Infinity;
       tmp = 0;
       for(i=1; i<=n; i++)
          if(min > Des[i])
          {
             min = Des[i];
             tmp = i;
          }
       if(tmp!=0)
          printf("%d %d\n",tmp, min);
       else
          printf("disjoint\n");
       scanf("%d",&n);
   }
  
   //system("pause");
   return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值