题目链接
1 /*
2 Name:NYOJ-203-三国志
3 Copyright:
4 Author:
5 Date: 2018/4/8 21:01:07
6 Description:
7 dijkstra+01背包
8 */
9 #include <cstring>
10 #include <cstdio>
11 #include<iostream>
12 using namespace std;
13
14 const int MAXN = 1000, INF = 0x3f3f3f3f;
15 int dis[MAXN], g[MAXN][MAXN], N, money[MAXN];
16 int dp[1000005];
17 bool v[MAXN];
18 void dijkstra() {
19 for (int i=0; i<=N; i++) dis[i] = INF;
20 dis[0] = 0;
21 memset(v, 0, sizeof(v));
22 for (int i=0; i<=N; i++) {
23 int mark = -1, mindis = INF;
24 for (int j=0; j<=N; j++) {
25 if(!v[j] && dis[j]<mindis) {
26 mindis = dis[j];
27 mark = j;
28 }
29 }
30 v[mark] = 1;
31 for (int j=0; j<=N; ++j) {
32 if (!v[j]) {
33 dis[j] = min(dis[j], dis[mark] + g[mark][j]);
34 }
35 }
36 }
37 }
38 int main()
39 {
40 int t;
41 cin>>t;
42 while (t--) {
43 memset(g, 0x3f, sizeof(g));
44 memset(dis, 0, sizeof(dis));
45 memset(money, 0, sizeof(money));
46 memset(dp, 0x3f, sizeof(dp));
47 int s, m;
48 cin>>s>>N>>m;
49 for (int i=1; i<=m; i++) {
50 int x, y, cost;
51 cin>>x>>y>>cost;
52 if (cost > g[x][y]) continue;
53 g[x][y] = g[y][x] = cost;
54 }
55 for (int i=1; i<=N; i++) {
56 cin>>money[i];
57 }
58 dijkstra();//求出最短路径
59 memset(dp,0,sizeof(dp));
60 for(int i=1; i<=N; ++i) //01背包
61 {
62 for(int j=s; j>=dis[i]; j--)
63 {
64 if(dp[j] < dp[j-dis[i]] + money[i])
65 dp[j] = dp[j-dis[i]]+money[i];
66 }
67 }
68 int ans = 0;
69 for(int i=1; i<=s; ++i)
70 ans = ans>dp[i]?ans:dp[i];
71 cout<<ans<<endl;
72 }
73 return 0;
74 }