POJ-1135 Domino Effect 单源最短路径

来源:互联网 发布:学而知不足 出处 编辑:程序博客网 时间:2024/06/05 00:42

http://poj.org/problem?id=1135

题目大意:一个极端多米诺骨牌游戏,计算出最后倒下的那一张牌倒下的时间。这些多米诺骨牌包含一些“关键牌”,当一张关键牌倒下,连接这张关键牌的所有行开始倒下,两个端点的关键牌可以同时倒下,则最后倒下的为两张关键牌中的一张普通牌。

题目思路:可以分为两种情况:(1)最后倒下的是关键牌,则是从源点即第一张牌到某张牌的最短距离。

(2)另一种情况为最后倒下的是普通牌,则时间为该行两个端点的关键牌倒下时间和,再加上行距离除以2。因为最后倒下的是行中的某一个普通牌,则该行是由两端同时向中间倒的。则最长时间是端点的两个关键牌倒下的时间再加上该行所有普通牌倒下的时间和的一半,因为是双向同时进行的。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 510
#define INF 0xfffffff
typedef struct node
{
        int u,v;        
}node;
node d[MAX];
int map[MAX][MAX];
int dist[MAX];
int s[MAX];
int n,m;
void dijkstra(int v0)
{
     int i,j,k;        
     for (i=1;i<=n;i++)
     {
         dist[i]=map[v0][i];    
         s[i]=0;
     }
     s[v0]=1;
     dist[1]=0;
     for (i=1;i<n;i++)
     {
         int min=INF,v=1;
         for (j=1;j<=n;j++)
         {
             if (!s[j]&&min>dist[j])
             {
                v=j;                       
                min=dist[j];
             }        
         }
         s[v]=1;
         for (j=1;j<=n;j++)
         {
                if (!s[j]&&dist[v]+map[v][j]<dist[j])
                {
                   dist[j]=dist[v]+map[v][j]; 
                }     
         }   
     }
}
int main()
{
    int tot=1;
    while (scanf("%d%d",&n,&m)!=EOF)
    {
          if (n==0&&m==0)
             break;
          int i,j,x,y,k=1;
          int u,v,w;
          float sum,max=0.0,max1=0.0;
          for (i=1;i<=n;i++)
          {
              for (j=1;j<=n;j++)
              {
                  map[i][j]=INF;
              }    
          }
          for (i=0;i<m;i++)
          {
              scanf("%d%d%d",&u,&v,&w);       
              d[i].u=u;
              d[i].v=v;
              map[u][v]=w;
              map[v][u]=w;
          }      
          dijkstra(1);
          for (i=1;i<=n;i++)    //第一种情况,就源点到某一个用时最长的点的时间。
          {
              //printf("%d\n",dist[i]);
              if (max1<dist[i])
              {
                 max1=dist[i];  
                 k=i;              
              }
          }
          for (i=0;i<m;i++)
          {
              u=d[i].u;
              v=d[i].v;
              sum=(dist[u]+dist[v]+map[u][v])/2.0;      
              if (sum>max)
              {
                 max=sum;
                 x=u;
                 y=v;     
              }
          }
          printf("System #%d\n",tot++);
          if (max1>=max)   //两种情况的时间对比。
          {
               printf("The last domino falls after %.1f seconds, at key domino %d.\n",max1,k);         
          }
          else
          {
              printf("The last domino falls after %.1f seconds, between key dominoes %d and %d.\n",max,x,y);    
          }
          printf("\n");
    }
    return 0;    

原创粉丝点击