首页 > 代码库 > poj 1135 最短路 dijkstra

poj 1135 最短路 dijkstra

传送门 http://poj.org/problem?id=1135

建模分两部分:1、如果最后是关键牌倒下,那么找最短路中最长的就行--最远的倒下,其他的牌一定倒下,所以找最远的最短路

                             2、如果最后是普通牌倒下,那么找三角形,三角形周长的一半就是倒下的位置

到底是情况1还是情况2,自己在脑子模拟一下就能想到,还是那句话,最难倒下的倒下了,其他的一定都倒下了,若第二种情况的时间比第一种长,那么就是第二种,反之,第一种

上代码

/**********************************    poj 1135 by pilgrim
    无向图边没来回弄
    少个空行PE....
    2014.6.23
\**********************************/
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
#define ll long long

const int SIZE = 500+10;
const int INF = 2000000000;
double e[SIZE][SIZE], d[SIZE];
bool s[SIZE];

int n,m;

void Init()
{
    for(int i=0;i<=n;i++)
        for(int j=0;j<=n;j++)
            e[i][j]=INF,d[i]=INF;
}

void AddEdge()
{
    int u,v;
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&u,&v);/*最小的下标为0*/
        scanf("%lf",&e[u-1][v-1]);
        e[v-1][u-1]=e[u-1][v-1];
    }
}

void dij(int cnt)
{
    for(int i=0;i<n;i++)
    {
        d[i]=e[0][i];
        s[i]=0;
    }
    d[0]=0,s[0]=1;
    for(int i=0;i<n-1;i++)
    {
        int mmin = INF,u=0;
        for(int j=0;j<n;j++)
            if(!s[j] && d[j] <mmin)
            {
                u=j;mmin=d[j];
            }
        s[u]=1;
        for(int k=0;k<n;k++)
        {
            if(!s[k] && e[u][k] < INF && d[u]+e[u][k]<d[k])
                d[k]=d[u]+e[u][k];
        }
    }
    double maxt1=-INF,maxt2=-INF,tmp;
    int pos,poss,pose;
    for(int i=0;i<n;i++)
        if(maxt1<d[i])
        {
            maxt1=d[i];
            pos=i;
        }
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        {
            if(d[i] <INF && d[j] < INF && e[i][j] < INF)
            {
                tmp=(d[i]+d[j]+e[i][j])/2.0;//
                if(tmp>maxt2)
                {
                    maxt2=tmp;
                    poss=i,pose=j;
                }
            }
        }
    printf("System #%d\n",cnt);
    if(maxt2>maxt1)printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.\n",maxt2,poss+1,pose+1);
    else printf("The last domino falls after %.1lf seconds, at key domino %d.\n",maxt1,pos+1);
    putchar('\n');
}
int main()
{
    int ncase=1;
    while(~scanf("%d%d",&n,&m), n+m)
    {
        Init();
        AddEdge();
        dij(ncase++);
    }
    return 0;
}