poj1135 Domino Effect

 这题之前以为就是找一条最长路径然后比较最长路径节点a和a相邻节点j,通过公式(dist[a]+dist[j]+mapp[a][j])算出的最大值就可以了
然后发现样例数据中出现了正权回路,那果断会陷入死循环,这样搞得我的思路也陷入死循环了,后来偶然间瞟见某大牛博客上说其实是单源最短路的最大值,
我仔细一想 恍然大悟,其实题目意思是骨牌以一种类似于广搜的倒法开始一路倒下去,那么每到一个关键点就可以发现和它邻接的边都会开始受到影响
那么这样走下去撑到最久的其实是最短路径中的最大值,由于可能终止点出现在边上,那么就需要比较一下最终结点周围的值,然后通过上述公式算出maxx2,
和maxx1做比较,看谁能够更大,那么就是能够撑到最后的情况。 其实样例数据已经很有针对性了,还有个细节要注意下,如果牌数只有1的话那么直接输出0.0,我就是在这里WA了2次

 

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
struct node
{
       int num;
       double value;      
};
const int size = 600;
const int eps = 10000000;
double dist[size];
vector <node> mapp[size];
void SPFA(int n, int s)
{
     queue <node> que;
     bool inque[size] = {false};
     for (int i = 1; i <= n; i ++)dist[i] = eps;
     node pre;
     pre.num = s;
     pre.value = 0.00;
     que.push(pre);
     dist[s] = 0.00;
     inque[pre.num] = true;
     while (!que.empty()){
           pre = que.front();
           que.pop();
           inque[pre.num] = false;
           int k = pre.num;
           for (int i = 0; i < mapp[k].size(); i ++){
               node t = mapp[k][i];
               if (dist[t.num] > dist[pre.num] + t.value){
                  dist[t.num] = dist[pre.num] + t.value;
                  if (!inque[t.num]){
                     inque[t.num] = true;
                     que.push(t);                  
                  }               
               }
           }     
     }
}
int main()
{
    int n, m;
    int nc = 0;
    while (scanf("%d%d", &n, &m) && (n|m)){
          for (int i = 0; i <= n; i ++){
              mapp[i].clear();
          }
          for (int i = 0; i < m; i ++){
              node a, b;
              scanf("%d%d%lf", &a.num, &b.num, &b.value);
              mapp[a.num].push_back(b);
              a.value = b.value;
              mapp[b.num].push_back(a);   
          }
          printf("System #%d\n", ++ nc);
          if (n==1){printf("The last domino falls after %.1lf seconds, at key domino 1.\n\n", 0 );continue;}
          SPFA(n, 1);
          int ndnum1, ndnum2;
          double max1 = -1.0, max2 = -1.0;
          for (int i = 1; i <= n; i ++){
              if (dist[i] > max1)max1 = dist[i],ndnum1 = i;   
          }
          for (int i = 0; i < mapp[ndnum1].size(); i ++){
              int k = mapp[ndnum1][i].num;
              double xxx = (mapp[ndnum1][i].value + dist[k] + max1)/2;
              if (xxx > max2 ){
                 max2 = xxx;
                 ndnum2 = k;
              }
          }
          if (max2 > max1 && ndnum1 > ndnum2)
             swap(ndnum1, ndnum2);
          max2 > max1?printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n\n", max2, ndnum1, ndnum2):printf("The last domino falls after %.1lf seconds, at key domino %d.\n\n", max1, ndnum1);
         
    }
   
    return 0;   
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值