Domino Effect(多米诺效应)

poj1135

题目大意:多米诺的关键点从1......n,把1推倒,求出最后倒下的是哪个,或者是两点中间倒下

解决:迪杰斯特拉求出从1到各个顶点的最短代价(此处为时间),找出最短代价中用时最长的那个,然后再枚举出在边中间到下的最长时间是哪两个点

比较下最长的即为所求的结果

#include <iostream>

#include <cmath>

#include <cstdio>

using namespace std;

#define MAX 0x3f3f3f3f

const int N=505;

int cost[N][N];

bool vis[N];

int dist[N];

int n;

void init()

{

    for(int i=1;i<=n;i++)

      for(int j=1;j<=n;j++)

      if(i==j)cost[i][j]=0;

      else cost[i][j]=MAX;

}

void dijikstra()

{

    int v0=1;

    for(int i=1;i<=n;i++)

    {

        vis[i]=0;

        dist[i]=cost[v0][i];

    }

    vis[v0]=1;

    for(int i=1;i<n;i++)

    {

        int min=MAX;

        for(int j=1;j<=n;j++)

           if(!vis[j] && dist[j]<min ){min=dist[j];v0=j;}

           vis[v0]=1;

        for(int j=1;j<=n;j++)

        if(!vis[j] && min+cost[v0][j]< dist[j])dist[j]=min+cost[v0][j];

    }

}

int main()

{

    int m,icase=1;

    while(scanf("%d%d",&n,&m),n||m)

    {

        int i,j,a,b,w;

        init();

        for(i=0;i<m;i++)

        {

            cin>>a>>b>>w;

            cost[a][b]=cost[b][a]=w;

        }

        dijikstra();

        double max=0;

        int pos=1;

        for(i=2;i<=n;i++)if(dist[i]>max){ max=dist[i]; pos=i;}

        int posa,posb;

        double res=0;

        //此处找出从边中间倒下的,因为是无向图,邻接矩阵一定是对称的题目要求是i<j

      //所以只需枚举下三角即可,(事实上,枚举全部我超时了)

        for(j=1;j<=n;j++)

          for(i=1;i<j;i++)


if( (cost[i][j]!=MAX) && ((dist[i]+dist[j]+cost[i][j])/2.0 > res ) ) {//若边存在而且满足在边的中间某点倒下,找出最长的时间
posa=i; posb=j; res=(dist[i]+dist[j]+cost[i][j])/2.0; } printf("System #%d\n",icase++); if(max>=res)//将在点倒下和在边中倒下比较 printf("The last domino falls after %.1lf seconds, at key domino %d.\n",max,pos); else printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n",res,posa,posb); printf("\n"); } system("pause"); return 0; }

你可能感兴趣的:(effect)