ACM: 图论题 poj 1135

来源:互联网 发布:mac下面的图标怎么换掉 编辑:程序博客网 时间:2024/05/22 00:28
                                       Domino Effect

 

Description

Did you know thatyou can use domino bones for other things besides playing Dominoes?Take a number of dominoes and build a row by standing them on endwith only a small distance in between. If you do it right, you cantip the first domino and cause all others to fall down insuccession (this is where the phrase ``domino effect'' comesfrom).

While this is somewhat pointless with only a few dominoes, somepeople went to the opposite extreme in the early Eighties. Usingmillions of dominoes of different colors and materials to fillwhole halls with elaborate patterns of falling dominoes, theycreated (short-lived) pieces of art. In these constructions,usually not only one but several rows of dominoes were falling atthe same time. As you can imagine, timing is an essential factorhere.

It is now your task to write a program that, given such a system ofrows formed by dominoes, computes when and where the last dominofalls. The system consists of several ``key dominoes'' connected byrows of simple dominoes. When a key domino falls, all rowsconnected to the domino will also start falling (except for theones that have already fallen). When the falling rows reach otherkey dominoes that have not fallen yet, these other key dominoeswill fall as well and set off the rows connected to them. Dominorows may start collapsing at either end. It is even possible that arow is collapsing on both ends, in which case the last dominofalling in that row is somewhere between its key dominoes. You canassume that rows fall at a uniform rate.

Input

The input filecontains descriptions of several domino systems. The first line ofeach description contains two integers: the number n of keydominoes (1 <= n < 500) and thenumber m of rows between them. The key dominoes are numbered from 1to n. There is at most one row between any pair of key dominoes andthe domino graph is connected, i.e. there is at least one way toget from a domino to any other domino by following a series ofdomino rows.

The following m lines each contain three integers a, b, and l,stating that there is a row between key dominoes a and b that takesl seconds to fall down from end to end.

Each system is started by tipping over key domino number 1.

The file ends with an empty system (with n = m = 0), which shouldnot be processed.

Output

For each case outputa line stating the number of the case ('System #1', 'System #2',etc.). Then output a line containing the time when the last dominofalls, exact to one digit to the right of the decimal point, andthe location of the last domino falling, which is either at a keydomino or between two key dominoes(in this case, output the twonumbers in ascending order). Adhere to the format shown in theoutput sample. The test data will ensure there is only onesolution. Output a blank line after each system.

Sample Input

2 1
1 2 27
3 3
1 2 5
1 3 5
2 3 5
0 0

Sample Output

System #1
The last domino falls after 27.0 seconds, at key domino 2.

System #2
The last domino falls after 7.5 seconds, between key dominoes 2 and3.

 

题意: 多米若骨牌, 从1开始推倒, 计算出最后的到的时间, 和两个关键位置,

     最后倒在行的终点或起点, 则关键位置只有一个, 中间就有两个.

 

解题思路:

         1. 可以用最短路dijkstra求出起点到每个关键位置的时间.

         2. 时间是计算最长的最短路, 显然, 最后的时间是i-->j中间的话,

       reult_time = (time[i] + time[j] +(直接路径时间)time[i->j]) / 2 (除以2是因为速度一样)

         3. 再从i->j中最大的值即可.

 

代码:

#include<cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 505
const int INF = (1<<29);

int n, m;
int g[MAX][MAX];
double result;
int state1, state2;
int dist[MAX];
bool vis[MAX];

void read_graph()
{
 int i, j;
 for(i = 1; i <= n; ++i)
  for(j = 1; j <=n; ++j)
  {
   if(i == j)g[i][j] = 0;
   else g[i][j]= INF;
  }

 int u, v, w;
 for(i = 1;  i<=m; ++i)
 {
  scanf("%d %d%d",&u,&v,&w);
  if(g[u][v] >w)
   g[u][v] =g[v][u] = w;
 }
}

int dijkstra(int start)
{
 int i, j;
 int min;
 memset(vis,false,sizeof(vis));
 for(i = 1; i <= n; ++i)
  dist[i] = (i == start ? 0 :INF);
 vis[start] = true;
 for(i = 1; i <= n; ++i)
 {
  min = INF;
  int u = start;
  for(j = 1; j <=n; ++j)
  {
   if(!vis[j]&& min >dist[j])
   {
    min= dist[j];
    u= j;
   }
  }
  vis[u] = true;
  for(j = 1; j <=n; ++j)
  {
   if(!vis[j]&& dist[j] > dist[u]+ g[u][j] )
   {
    dist[j]= dist[u] + g[u][j];
   }
  }
 }

 int maxt = 0;
 for(i = 1; i <= n; ++i)
 {
  if(maxt <dist[i] && dist[i] != INF)
  {
   maxt =dist[i];
   state1 =i;
  }
 }
 return maxt;
}

int main()
{
// freopen("input.txt","r",stdin);
 int k = 1;
 int i, j;
 while(scanf("%d%d",&n,&m) != EOF)
 {
  if(n == 0&& m == 0) break;
  if(n == 1)
  {
   printf("System#%d\n",k++);
   printf("Thelast domino falls after 0.0 seconds, at key domino 1.\n\n");
   continue;
  }

  read_graph();
  result = dijkstra(1);

  bool flag =false;
  for(i = 1; i <=n; ++i)
  {
   for(j = i+1;j <= n; ++j)
   {
    if(g[i][j]!= INF)
    {
     doublex = (dist[i] + dist[j] + g[i][j]) / 2.0;
     if(result< x)
     {
      flag= true;
      result= x;
      state1= i;
      state2= j;
     }
    }
   }
  }

  printf("System#%d\n",k++);
  if(!flag)
   printf("Thelast domino falls after %.1lf seconds, at key domino%d.\n\n",result,state1);
  else
   printf("Thelast domino falls after %.1lf seconds, between key dominoes %d and%d.\n\n",result,state1,state2);
 }
 return 0;
}

 

0 0
原创粉丝点击