Sicily 1034. Forest

本文详细介绍了如何通过宽度优先搜索算法计算森林的深度和宽度,包括算法流程、注意事项及代码实现,特别强调了避免常见陷阱的方法。

要明确的是这是一个森林,存在很多棵树,我们需要判断输入是否满足产生多颗树的要求,然后再输出森林的深度和宽度。这题有一些陷阱很容易让人判断出错,即使我AC后在写这个解题报告时,也发现了我的代码存在漏洞,可见出题者也没有考虑到一些特殊情况。
我最终修改后的的方法是:首先把所有的根找出来,然后利用宽度优先检索对每一棵树进行分层遍历,并跟踪记录层数和最大的每层数目,作为森林的深度和宽度。遍历过程中,若发现某一节点试图访问已经被访问过的节点时,表示某棵树存在环或者某两个节点同时指向一个节点的情况,这时要及时标记。遍历完毕后还要判断下是否每个节点都被访问过了,因为这是以森林中所有的根为基点往上遍历的,原则上每个点都会被访问,否则表示存在独立的不成树的节点群,这也不符合森林的特点。我先前的另一个AC代码和这个方法有比较大的不同,但在逻辑判断上就是漏了最后一种情况,即存在独立的不成树的节点群没有却被有效地判断出来。

Run Time: 0sec
Run Memory: 312KB
Code length: 2054Bytes
SubmitTime: 2011-12-24 22:34:02

// Problem#: 1034
// Submission#: 1123477
// 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 <iostream>
#include <queue>
#include <cstring>
using namespace std;

int main()
{
    int n, m;
    int i, j;
    int parent;
    int depth, width;
    bool valid, bottom;
    bool visited[ 101 ];
    bool edge[ 101 ][ 101 ];

    while ( cin >> n >> m && n ) {
        memset( visited, false, sizeof( visited ) );
        memset( edge, false, sizeof( edge ) );

        while ( m-- ) {
            cin >> i >> j;
            edge[ i ][ j ] = true;
        }

        queue<int> q;
        for ( i = 1; i <= n; i++ ) {
            for ( j = 1; j <= n; j++ ) {
                if ( edge[ j ][ i ] )
                    break;
            }
            if ( j > n ) {
                q.push( i );
                visited[ i ] = true;
            }
        }

        depth = 0;
        width = q.size();
        valid = ( q.size() != 0 ? true: false );
        while ( valid && !q.empty() ) {
            parent = q.size();
            if ( parent > width )
                width = parent;
            bottom = true;
            while ( valid && parent-- ) {
                i = q.front();
                for ( j = 1; valid && j <= n; j++ ) {
                    if ( edge[ i ][ j ] ) {
                        bottom = false;
                        if ( visited[ j ] )
                            valid = false;
                        else {
                            q.push( j );
                            visited[ j ] = true;
                        }
                    }
                }
                q.pop();
            }
            if ( bottom == false )
                depth++;
        }

        if ( valid ) {
            for ( i = 1; i <= n; i++ ) {
                if ( !visited[ i ] ) {
                    valid = false;
                    break;
                }
            }
        }

        if ( valid )
            cout << depth << " " << width << endl;
        else
            cout << "INVALID" << endl;
    }

    return 0;

}                                 


 

(Kriging_NSGA2)克里金模型结合多目标遗传算法求最优因变量及对应的最佳自变量组合研究(Matlab代码实现)内容概要:本文介绍了克里金模型(Kriging)与多目标遗传算法NSGA-II相结合的方法,用于求解最优因变量及其对应的最佳自变量组合,并提供了完整的Matlab代码实现。该方法首先利用克里金模型构建高精度的代理模型,逼近复杂的非线性系统响应,减少计算成本;随后结合NSGA-II算法进行多目标优化,搜索帕累托前沿解集,从而获得多个最优折衷方案。文中详细阐述了代理模型构建、算法集成流程及参数设置,适用于工程设计、参数反演等复杂优化问题。此外,文档还展示了该方法在SCI一区论文中的复现应用,体现了其科学性与实用性。; 适合人群:具备一定Matlab编程基础,熟悉优化算法和数值建模的研究生、科研人员及工程技术人员,尤其适合从事仿真优化、实验设计、代理模型研究的相关领域工作者。; 使用场景及目标:①解决高计算成本的多目标优化问题,通过代理模型降低仿真次数;②在无法解析求导或函数高度非线性的情况下寻找最优变量组合;③复现SCI高水平论文中的优化方法,提升科研可信度与效率;④应用于工程设计、能源系统调度、智能制造等需参数优化的实际场景。; 阅读建议:建议读者结合提供的Matlab代码逐段理解算法实现过程,重点关注克里金模型的构建步骤与NSGA-II的集成方式,建议自行调整测试函数或实际案例验证算法性能,并配合YALMIP等工具包扩展优化求解能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值