题目描述:
有一个魔法迷宫,它的道路是单向的,沿着这条路走不会到达同一个休息区(迷宫是无环的)。迷宫中有n个休息区和m条道路。有些路让你得到宝藏,而有些路让你失去宝藏。你应该选择出发的地方,并尽可能多地获得宝物。
请注意,对于每条道路,您只能通过一次。
输入描述:
第一行:案例T的数量(1≤T≤110)
在每个测试案例中:
第一行是两个整数:休息区数量n,道路数量m(1≤n≤1000,0≤m ≤n×(n−1)÷2) m 行,每行三个整数:开头u,结尾v,宝藏w(0≤u<n,0≤v<n,−1000≤w≤1000)
输出描述:
T行,每行一个整数,最大宝藏是多少
输入:
2
5 4
0 1 -10
1 2 10
2 3 10
3 4 -10
4 4
0 1 4
0 2 5
2 3 -2
3 1 4
输出:
20
7
说明:
在第一个例子中,你可以走 1 ->2 >3,那么 ans 是 10+10=20
在第二个例子中,你可以走 0 ->2 ->3>-1,那么 ans 是 5−2 +4=7
心历路程: 首先看到这个问题肯定会想到用dfs加动态规划来做(因为有不同的路径,又要求最大值) 但最开始我就根据自己想的 先用start数组找到起点 再从起点依次使用dfs找到路径再找到最大值 最后虽然过了例子但超时了,然后看了别人的优化才明白自己压根就没用到动态规划 把这道题做成了dfs的题
我的错误: 刚开始用dfs的是多加一个参数(加上这一次的最大值)导致只能一次一次加 当有多条路径时就会多计算 就没有动态规划那样减少时间。下面这张图就很清晰说明,其实错误做法就是dfs来找出有多少条路径 再每条路径计算一遍,其实有的重复就不需要了 所以感触良多。(第二个就是下面代码的做法)最后再给出我的错误做法;
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
struct node{
int next,tre;
node(int nn,int tt):next(nn),tre(tt){}//参数构造函数
node(){}//默认构造函数
};
vector<node> road[1005];
int start[1005];
int dp[1005];
int dfs(int n){
if(dp[n]>0)return dp[n];
int ans=0;
for(int i=0;i<road[n].size();i++){
ans=max(ans,dfs(road[n][i].next)+road[n][i].tre);
}
dp[n]=ans;
return dp[n];
}
int main()
{
int T,n,m;
cin>>T;
int a,b,c;
while(T--){
cin>>n>>m;
memset(start,0,sizeof(start));
memset(dp,0,sizeof(dp));
for(int i=0;i<m;i++){
cin>>a>>b>>c;
road[a].push_back(node(b,c));
start[b]=1;
}
for(int i=0;i<n;i++){
if(start[i]==0){
dfs(i);
}
}
cout<<*max_element(dp,dp+n)<<endl;//返回dp数组中最大值
for(int i=0;i<n;i++)road[i].clear();//将路径清零
}
}
//错误做法 请勿模仿
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
struct node{
int destination,Treasure;
node(int dd,int tt):destination(dd),Treasure(tt){}
node(){}
};
vector<node> road[1005];
int start[1005];
int maxlen;
int n,m;
void dfs(int n,int max_num){
for(int i=0;i<road[n].size();i++){
int mid_num=max_num;
if(mid_num>0)mid_num+=road[n][i].Treasure;
else mid_num=road[n][i].Treasure;
maxlen=max(maxlen,mid_num);
dfs(road[n][i].destination,mid_num);
}
return;
}
int main()
{
int T;
cin>>T;
int a,b,c;
while(T--){
cin>>n>>m;
memset(start,0,sizeof(start));
for(int i=0;i<m;i++){
cin>>a>>b>>c;
road[a].push_back(node(b,c));
start[b]=1;
}
maxlen=0;
for(int i=0;i<n;i++){
if(start[i]==0){
dfs(i,0);
}
}
cout<<maxlen<<endl;
for(int i=0;i<n;i++)road[i].clear();
}
}