每日一题——高手去散步

112 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情

题目描述

高手最近谈恋爱了。不过是单相思。“即使是单相思,也是完整的爱情”,高手从未放弃对它的追求。今天,这个阳光明媚的早晨,太阳从西边缓缓升起。于是它找到高手,希望在晨读开始之前和高手一起在鳌头山上一起散步。高手当然不会放弃这次梦寐以求的机会,他已经准备好了一切。

鳌头山上有n个观景点,观景点两两之间有游步道共m条。高手的那个它,不喜欢太刺激的过程,因此那些没有路的观景点高手是不会选择去的。另外,她也不喜欢去同一个观景点一次以上。而高手想让他们在一起的路程最长(观景时它不会理高手),已知高手的穿梭机可以让他们在任意一个观景点出发,也在任意一个观景点结束。

输入格式

第一行,两个用空格隔开的整数n、m. 之后m行,为每条游步道的信息:两端观景点编号、长度。

题目描述

一个整数,表示他们最长相伴的路程。

输入输出样例

输入 #1复制

4 6
1 2 10
2 3 20
3 4 30
4 1 40
1 3 50
2 4 60

输出 #1复制

150

说明/提示

对于100%的数据:n≤20,m≤50,保证观景点两两之间不会有多条游步道连接

思路

这道题是一道经典的dfs和图的遍历相结合的题目。本题只需要想明白两个问题:

1、怎么存储点与点之间的信息;

2、怎么遍历每一条路线;

问题一: 这显然是一个无向图,又因为无向图可以看成是特殊的有向图,在存储边的时候a到b存一条,b到a存一条。所以我们只需要考虑如何存储一个有向图,我们这里使用的是邻接矩阵q[a,b],表示的是a到b的一条路线,其本身的值就是我们的路线权值;

问题二: 根据题目意思,我们可以从任意点出发,在任意点结束,所以我们需要循环dfs每一个点,考虑到每一条路线,然后求其最大值;两点之间可以走的条件是两点之间有路线并且没有走过。

搞清楚这两个问题后,我们可以很好的编写代码。

代码

#include <iostream>
#include <algorithm>
#include <cstring>using namespace std;
​
const int N = 110;
​
int q[N][N];
bool visit[N];
int n, m;
int ans = 0, res = 0;
​
void dfs(int x)
{
    visit[x] = true;
    // 搜索每一条出路 
    for(int i = 1;i <= n;i ++)
    {
        // 如果两点之间有路可以走并且没有走过 
        if(q[x][i] && !visit[i])
        {
            visit[i] = true;
            ans += q[x][i];
            dfs(i); 
            // 恢复现场 
            visit[i] = false;
            ans -= q[x][i];
        }
            
    }
    //当无法达到下一层时(走到尽头或者所有点都被访问过),就统计此时的最长路,然后更新答案
    res = max(res, ans);
    
}
​
int main()
{
    
    cin >> n >> m;
    for(int i = 0;i < m;i ++)
    {
        int a , b, c;
        cin >> a >> b >> c;
        // 无向图的存储
        q[a][b] = q[b][a] = c;
            
    } 
    // 挨个搜索每个点 
    for(int i = 1;i <= n;i ++)
    {
        dfs(i);
        // 恢复距离
        memset(visit, false, sizeof visit);
    }
    
    cout << res << endl;
    return 0;
 }