CSU暑期集训day05_DFS_单源最大权路径

题目:

有一棵由N个结点构成的树,每一条边上都有其对应的权值。现在给定起点,求从该点出发的一条路径(至少有一条边)使得这条路径上的权值之和最大,并输出这个最大值。

Input

第一行一个正整数T,代表数据组数。每组数据第一行两个正整数n(2<=n<=10^5),s(1<=s<=n),分别表示树结点数目以及给定的起点,点的编号从1至N。接下来M行,每行三个整数x,y,z,(1<=x,y<=n,|z|<=1000),代表编号为x和y的点之间有一条权值为z的双向边。

Output

每组数据输出一行,即所找到路径的最大权值(格式参见样例)。

Sample Input

2
3 1
1 2 10
1 3 5
5 5
1 5 70
4 3 100
5 3 -10
2 5 60

Sample Output

Case #1: 10
Case #2: 90

解题思路:

    这题思路比较明确,由指定点出发深度优先遍历,无路可走的时候就可以结束,将当前路径权值参与比较选出最大的。我做这道题的时候却一波三折,主要是在纠结结点的存储问题,因为题目要求点的数目较多,直接设置二维数组存储会报错,然后我改用vector弄个二维数组,却还是报错,又改用结构体,结构体元素中有个邻居数组,点的数目有100000,也只好给邻居数组也设置大小100000,然后再用vector,还是报错,,,,所幸最后终于弄对了,出现这种情况的根本原因还是自己太菜了,对stl使用不熟练,不灵活。

代码:

#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

struct edge{
    int num;
    int weight;
};
vector<edge> ve[100002];

int n,s;
bool visi[100002];
long long int maxa=0;

void dfs(int s,int ans){
    visi[s]=true;
    for(int i=0;i<ve[s].size();i++){
        if(!visi[ve[s][i].num]){
            dfs(ve[s][i].num,ans+ve[s][i].weight);
        }
    }  
    if(ans>maxa)maxa=ans;   
    visi[s]=false;
}

int main(){
    int t;
    cin>>t;
    for(int c=1;c<=t;c++){    
        maxa=0;
        memset(visi,false,sizeof(visi));    
        cin>>n>>s;
        for(int i=0;i<=n;i++)ve[i].clear();        
        int x,y,z;
        int e=n-1;
        while(cin>>x>>y>>z){          
            edge a;
            a.num=y;
            a.weight=z;
            ve[x].push_back(a);
            a.num=x;
            ve[y].push_back(a);
            e--;
            if(e==0)break;
        }     
        dfs(s,0);      
        cout<<"Case #"<<c<<": "<<maxa<<endl;        
    } 
    system("pause");
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值