题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=679
思路:题意就是从想买的物品出发,走到尽头,找到这些路中最短的那个值。重点在于设置一个数组,记录一下搜索过的结果,避免重复搜索。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
using namespace std;
vector <int> g[1005];
int n, m, s, ans;
int p[1005], visit[1005], path[1005];
void init();
void read();
int dfs(int v);
int main(){
int T, i, k;
scanf("%d", &T);
for(k = 1; k <= T; k++){
scanf("%d %d %d", &n, &m, &s);
for(i = 1; i <= n; i++)
scanf("%d", &p[i]);
init();
read();
memset(visit, 0, sizeof(visit));
memset(path, 0, sizeof(path));
ans = dfs(s);
printf("Case #%d: %d\n", k, ans);
}
return 0;
}
int dfs(int v){
int i, t;
if(path[v])
return path[v];//path数组记录搜索过的结果,每次一进递归首先判断这个点之前有没有搜过,若有,直接返回之前的结果
if(g[v].size() == 0)
return p[v];//若搜到了尽头,返回叶子节点的值
else{
int temp = 65535;//否则,返回最优解,temp初始化为极大值,找到从此点出发走到尽头的最短路,即最优解
for(i = 0; i < g[v].size(); i++){
t = dfs(g[v][i]);
if(temp > t + p[v])
temp = t + p[v];
}
path[v] = temp;//记录从v出发搜索的结果
return temp;
}
}
void read(){
int i, j, k;
for(i = 0; i < m; i++){
scanf("%d %d", &j, &k);
g[j].push_back(k);
}
}
void init(){
int i;
for(i = 1; i <= n; i++)
g[i].clear();
}