最短路径-Dijkstra(poj 1135)

10 篇文章 0 订阅

题意:

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


分析:

最后倒下的牌 有两种情形:

① 如果最后倒下的牌是关键牌,其时间及位置就是第 1 张关键牌到其他关键牌中短路径的最大值及对应的关键牌;

② 如果最后倒下的牌是两张关键牌之间的某张普通牌,其时间是这一行的两个关键骨牌到1骨牌的最短时间加上这一行的时间再除以2,位置为这两张关键牌之间的某张普通牌。

所以实质上就是最短路+枚举;

注:

小心 1 0 这组数据。这组数据仍然有效 输出应该是0.0s 在 1 位置

代码:

#include <queue>
#include <iostream>
#include <string.h>
#include <vector>
#include <cstdio>
using namespace std;
const int MAX_N = 510;
const int MAX = 1 << 30;
int map[MAX_N][MAX_N];
int dist[MAX_N];
int N, M;

struct cmp{
  bool operator()(int a, int b)
  {
    return dist[a] > dist[b];
  }
};

priority_queue<int, vector<int>, cmp> Q;

void Dijkstra(int start)
{
  for(size_t i = 1; i <= N; ++i)
    dist[i] =MAX;
  Q.push(start);
  dist[start] = 0;
  while(!Q.empty())
  {
    int idx = Q.top();
    Q.pop();
    for(size_t i = 1; i <= N; ++i)
    {
      if((dist[idx] + map[idx][i]) < dist[i])
      {
        Q.push(i);
        dist[i] = dist[idx] + map[idx][i];
      }
    }
  }
}
int main()
{
  int cnt = 1;
  while( cin >> N >> M)
  {
    if(N == 0 && M == 0)
      break;
    for(size_t i = 0; i <= N; ++i)
      for(size_t j = 0; j <= N ; ++j)
        map[i][j] = MAX;
    for(size_t i = 1; i <= N; ++i)
      map[i][i] = 0;
    for(size_t i = 0; i < M; ++i)
    {
      int u, v, cost;
      cin >> u >> v >> cost;
      map[u][v] = cost;
      map[v][u] = cost;
    }
    Dijkstra(1);
    double res = -1.0f;
    int idx1, idx2, idx3;
    idx1 = 1;
    for(size_t i = 1; i <=N; ++i)
    {
      if(dist[i] > res)
      {
        res = dist[i];
        idx1 = i;
      }
    }
    double tmp;
    idx2 = -1;
    for(size_t i = 1; i <=N; ++i)
      for(size_t j = i + 1; j <= N ;++j)
      {
        if(map[i][j] != MAX)
        {
          tmp = (dist[i] + dist[j] + map[i][j]) / 2.0f;
          if(tmp > res)
          {
            res = tmp;
            idx2 = i;
            idx3 = j;
          }
            
        }
      }
    cout << "System #" << cnt << endl;
    if(idx2 == -1)
      printf("The last domino falls after %.1f seconds, at key domino %d.\n\n",res, idx1);
    else 
      printf("The last domino falls after %.1f seconds, between key dominoes %d and %d.\n\n", res, idx2, idx3);
    cnt++;
  }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值