POJ_1734 Sightseeing trip(拓扑)

本文介绍了一种使用深度优先搜索(DFS)解决寻找图中最短环的方法。通过遍历每个节点并进行剪枝操作,算法有效地找到了可能存在的最短环。详细解释了算法流程、边界条件处理及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目请点我
题解:
这是一道简单的深搜,找到最短的一个环。深搜遍历每一个点,注意剪枝,边为双向边,并且可能会有重边。
代码实现:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#define MAX_N 110
#define MAX_M 10010
#define INF 0x7fffffff

using namespace std;

int N,M;
int result;
int start;
int length;
bool flag;
//深搜时更新的数组
int lis[MAX_N];
//保存结果的数组
int save[MAX_N];
int visit[MAX_N];
int point[MAX_N][MAX_N];
//更新结果
void refresh(int len,int sum);
void dfs(int last,int pos,int len,int sum);
int main()
{
    while( scanf("%d%d",&N,&M) != EOF ){
        result = INF;
        flag = false;
        for( int i = 1; i <= N; i++ ){
            for( int j = 1; j <= N; j++ ){
                point[i][j] = INF;
            }
            lis[i] = 0;
            save[i] = 0;
            visit[i] = 0;
        }
        int x,y,l;
        for( int i = 0; i < M; i++ ){
            scanf("%d%d%d",&x,&y,&l);
            //有重边,双向边
            if( point[x][y] > l ){
                point[x][y] = l;
                point[y][x] = l;
            }
        }
        for( int i = 1; i <= N; i++ ){
            start = i;
            lis[0] = i;
            dfs(-1,i,0,0);
            lis[0] = 0;
        }
        if( flag ){
            for( int i = 0; i < length; i++ ){
                printf("%d",save[i]);
                if( i != length-1 ){
                    printf(" ");
                }
                else{
                    printf("\n");
                }
            }
        }
        else{
            printf("No solution.\n");
        }
    }
    return 0;
}

void dfs(int last, int pos,int len,int sum){
    if( pos == start && len != 0 ){
        if( result > sum ){
            refresh(len,sum);
        }
        return ;
    }
    //剪枝
    if( sum > result ){
        return ;
    }
    for( int i = 1 ; i <= N; i++ ){
        //相邻边&&未访问&&不是上一个节点
        if( point[pos][i]!=INF && visit[i]==0 && i != last ){
            lis[len+1] = i;
            visit[i] = 1;
            dfs(pos,i,len+1,sum+point[pos][i]);
            lis[len+1] = 0;
            visit[i] = 0;
        }
    }
    return ;
}

void refresh(int len,int sum){
    for( int i = 0; i < len; i++ ){
        save[i] = lis[i];
    }
    flag = true;
    result = sum;
    length = len;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值