HDU-2066 一个人的旅行(图论,Floyd ,最短路)

比这一题更简单粗暴的:HDU 2544 不用优化就过 = =


Input:

 输入数据有多组,每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个;
接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车程是time小时;(1=<(a,b)<=1000;a,b之间可能有多条路)
接着的第T+1行有S个数,表示和草儿家相连的城市;
接着的第T+2行有D个数,表示草儿想去地方。



Output:

输出草儿能去某个喜欢的城市的最短时间。




一开始用 Floyd 算法,毫无优化,超时的太带感了 = =

题目稍微有个小坑,之间可能有多条路,所以输入的时候就要注意,将两个城市之间花费最小的时间存起来,多的扔掉。

其实不是很明白 Floyd 算法...按自己的理解是以 K 为中介点,枚举所有任意两个城市的距离,

i 点 与 j 点,将时间花销最小的存在数组内。

两个城市不能通路,就将这两个城市的时间花销初始化为最大,INF 。


250ms代码(附送注释):

#include<cstdio>
#include<cstring>
#include <cmath>
#include<algorithm>
using namespace std;
const int INF = 1<<27;
const int MAXN = 1000+5;
int path[MAXN][MAXN];
bool start[MAXN];
bool destination[MAXN];
int maxid;
int Floyd ( void )
{
    int mini = INF;

    for( int k = 1; k<=maxid;++k)
        for( int i = 1; i<=maxid;++i )

          if( path[i][k]!=INF )//优化:INF 此路不通 不必再做无谓的比较
            for( int j = 1; j<=maxid;++j)
                {
                        if( path[i][j] > path[i][k] + path[k][j] )
                            path[i][j] = path[i][k] + path[k][j];
                            
                        // 每句所有 从不同的开始地点 到 目的地 花费的时间,找出最小的
                        
                        if ( start[i] && destination[j] && ( mini > path[i][j] ) )
                             mini = path[i][j];
                }

    return mini;
}
int main()
{


    int t,s,d;
    int link;
    int a,b,temp;

    while( ~scanf("%d %d %d",&t,&s,&d))
    {
        for( int i=0; i<MAXN; ++i)
            for( int j = 0; j<MAXN ;++j)
                path[i][j] = INF;


        maxid = 0;

        while ( t-- )
        {
            scanf("%d %d %d",&a,&b,&temp);
            maxid = max( a,max( b, maxid)); // 优化 比较次数
            path[a][b] = path[b][a] = min(temp,path[a][b]);// 之间可能有多条路径,选取花费时间最少的

        }// end of path's data


        memset(start,false,sizeof(start));
        memset(destination,false,sizeof(destination));

        while(s--)
        {
            scanf("%d",&link);
            start[link] = true;
            
        }//出发城市
        
        while(d--)
        {
            scanf("%d",&link);
            destination[link] = true;
        }//目的地城市
        
        // end of cities's data

        printf( "%d", Floyd() );
        puts("");
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值