解题思路:Dijkstra算法(单源最短路径)和0-1背包,但是要考虑重边

#include<stdio.h>
#include<vector>
#include<string.h>
#include<iostream>
using namespace std;
vector < pair<int, int> > G[105];
const int INF = 1000000;
int Dij[105];
int isVisit[105];
int City[105];
int f[1000002];
int S, N, M;
void Init(){
 int i;
 for(i = 0; i <= N; i++){
  G[i].clear();
  Dij[i] = INF;
 }
 memset(isVisit, 0, sizeof(isVisit));
 memset(f, 0, sizeof(f));
}
void Dijkstra(int begin){
 int i, v, weight;
 Dij[begin] = 0;
 while(isVisit[begin] == 0){
  isVisit[begin] = 1;
  for(i = 0; i < G[begin].size(); i++){
   v = G[begin][i].first;
   weight = G[begin][i].second;
   if(Dij[v] > Dij[begin] + weight)
    Dij[v] = Dij[begin] + weight;
  }
  int min_cost = INF;
  for(i = 0; i <= N; i++){
   if(!isVisit[i] && Dij[i] < min_cost){
    min_cost = Dij[i];
    begin = i;
   }
  }
 }
}
int pack(){
 int i, j;
 for(i = 1; i <= N; i++){
  for(j = S; j >= 0; j--){
   if(j >= Dij[i])
    f[j] = f[j] > f[j - Dij[i]] + City[i] ? f[j] : f[j - Dij[i]] + City[i];
  }
 }
 return f[S];
}
int main(){
 int T, i, max_cost;
 scanf("%d", &T);
 while(T--){
  scanf("%d%d%d", &S, &N, &M);
  Init();
  for(i = 0; i < M; i++){
   int x, y, len;
   scanf("%d%d%d", &x, &y, &len);
   G[x].push_back(make_pair(y, len));
   G[y].push_back(make_pair(x, len));
  }
  for(i = 1; i <= N; i++)
  scanf("%d", &City[i]);
  Dijkstra(0);
  max_cost = pack();
  printf("%d\n", max_cost);
 }
 return 0;

}
作业 二十七 三国志

作业 二十七 三国志


相关文章: