Sicily 1024. Magic Island

最开始时,是在BBS看见有人对这道题表示愤慨,全文如下:
“这道蛋疼题主要是求单源点到其他点最远距离。哥看到它第一印象就想到用dijkstra直接爆它,没多想用二维数组存储方式就很快写完了,恶心的是爆内存了。回头
看下题目数据,就果断采用邻接表,想这次该行了吧,结果妈的又TLE。这时哥开始萎了,爬起来最后一次,采用优先队列+dijkstra,终于过了,消耗了哥多少精子,生活不容易。”

后面的跟帖有各种回复,我就不予置评了……后来在Course中也碰到这道题,利用深搜,很幸运,一次AC。再后来想起那个帖子,试下Dijkstra,果然超时……

或许有人觉得深搜难以解决这个问题,其实题中有个细节,就是在这n个城市中,可以任意的从一个城市到另一个城市(即具有连通性),但却只有n-1条边,这些特点说明了这其实是一棵树。那么深搜遍历自然可以完美地解决这个问题。

Run Time: 0.11sec

Run Memory: 1172KB

Code length: 1411Bytes

SubmitTime: 2011-12-27 19:53:42

// Problem#: 1024
// Submission#: 1137874
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

struct Road {
    int to;
    int distance;
    Road( int t, int d ) { to = t; distance = d; }
};

int longest;
bool visited[ 10001 ];
vector<Road> road[ 10001 ];

void DFS( int n, int dist ) {
    bool deeper = false;
    for ( vector<Road>::iterator it = road[ n ].begin(); it != road[ n ].end(); it++ ) {
        if ( !visited[ it->to ] ) {
            visited[ it->to ] = true;
            deeper = true;
            DFS( it->to, dist + it->distance );
        }
    }
    road[ n ].clear();
    if ( !deeper && dist > longest )
        longest = dist;
}


int main()
{
    int N, K;
    int X, Y, D;

    while ( scanf( "%d%d", &N, &K ) != EOF ) {
        for ( int i = 1; i < N; i++ ) {
            scanf( "%d%d%d", &X, &Y, &D );
            road[ X ].push_back( Road( Y, D ) );
            road[ Y ].push_back( Road( X, D ) );
        }

        longest = 0;
        memset( visited, false, sizeof( visited ) );
        visited[ K ] = true;
        for ( vector<Road>::iterator it = road[ K ].begin(); it != road[ K ].end(); it++ ) {
            if ( !visited[ it->to ] ) {
                visited[ it->to ] = true;
                DFS( it->to, it->distance );
            }
        }
        road[ K ].clear();
        printf( "%d\n", longest );
    }

    return 0;

}                                 


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值