poj 1135 Domino Effect(dij)

题意:(看了半天没整明白) 有一个多米诺骨牌的游戏,我们知道有关键骨牌和普通骨牌,将关键骨牌推倒之后,整个骨牌阵就会倒下,推动其他的关键骨牌,其中推倒关键骨牌A使的关键骨牌B也倒,需要一定的时间,所以本题要求求出最后一个倒的骨牌的位置,及其时间...每个骨牌阵都由关键骨牌1推起

思路:对于倒的是关键骨牌我们可以通过Dijkstra来实现,而对于在中间倒的我们注意到一个现象——它所用的时间必然是这一行的两个关键骨牌到1骨牌的最短时间加上这一行的时间再除以2!!!用Dijkstra求出1点到其他点的最短时间,从中选个最大的MAX 然后求每行中间的,再求出最大的MAXJ然后比较MAXI和MAXJ的大小。

//      1176K      0MS
#include <stdio.h>
#include <string.h>
const int inf = 0x3f3f3f3f;
#define M 505

int mat[M][M];
int n;
void dij (int src)
{
      double dis[M];
      int mark[M],loc[2];
      int k,i,j;
      for (i = 1; i <= n; i ++)
      {
              dis[i] = mat[src][i];
              mark[i] = 0;
      }
      dis[src] = 0;
      mark[src] = 1;
      int m = n - 1;
      while (m --)
      {
              int min = inf;
              for (i = 1; i <= n; i ++)
                      if (!mark[i]&&dis[i] < min)
                      {
                              k = i;
                              min = dis[i];
                      }
              mark[k] = 1;
              for (i = 1; i <= n; i ++)
                      if (!mark[i] && dis[i] > dis[k] + mat[k][i])
                              dis[i] = dis[k] + mat[k][i];

      }
      double max = 0;
      for (i = 2; i <= n; i ++)
              if (dis[i] > max)
              {
                      k = i;
                      max = dis[i];
              }
      double maxj = 0;
      for (i = 1;i <= n;i ++)
              for (j = i+1;j <= n;j ++)
              {
                      if (mat[i][j] != inf)
                      {
                              double tem = (dis[i] + dis[j] + mat[i][j])/2;
                              if (tem > maxj)
                              {
                                      maxj = tem;
                                      loc[0] = i;
                                      loc[1] = j;
                              }

                      }
              }
      if (maxj > max)
              printf ("The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n\n",maxj,loc[0],loc[1]);
      else
              printf ("The last domino falls after %.1lf seconds, at key domino %d.\n\n",max,k);

}
int main ()
{
      int m,i,j,u,v,w;
      int count = 0;
      while (scanf ("%d%d",&n,&m))
      {
              if (n == 0&&m == 0)
                      break;
              memset (mat,0x3f,sizeof(mat));
              while (m --)
              {
                      scanf ("%d%d%d",&u,&v,&w);
                      mat[u][v] = w;
                      mat[v][u] = w;
              }
              printf ("System #%d\n",++count);
              if (n == 1)
                      printf ("The last domino falls after 0.0 seconds, at key domino 1.\n\n");
              else
                      dij (1);
      }
      return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值