非负权的单源最短路径,果断用dijkstra算法
需要注意的是这里是有交易的双方是有等级限制的,假设族长等级为Level0,最大可交易等级差为M,解决方案是,依次假设旅行者的等级为 Level0-M、Level0-M+1、Level0-M+2.......Level0+M,然后让旅行者只和等级不低于他的人交易,然后比较这2M+1次的结果,取最小值。
//Memory Time
//292K 16MS
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct edge
{
edge* next;
int dst;
int cost;
};
edge* eg[101];
struct vertex
{
int src;
int level;
int cost;
};
vertex vex[101];
bool cmp(vertex &a, vertex &b)
{
return a.cost > b.cost;
}
int main()
{
int M, N;
cin >> M >> N;
for(int i = 0; i <= N; i++)
eg[i] = NULL;
for(int i = 0; i < N; i++)
{
int price, level, num;
cin>>price>>level>>num;
vex[i].src = i;
vex[i].level = level;
vex[i].cost = 2000000000;
edge* e = new edge;
e->next = eg[N];
e->dst = i;
e->cost = price;
eg[N] = e;
for(int j = 0; j < num; j++)
{
int src, price;
cin >> src >> price;
src--;
edge* e = new edge;
e->next = eg[src];
e->dst = i;
e->cost = price;
eg[src] = e;
}
}
int minCost = 2000000000;
for(int t = M; t >= 0; t--)
{
for(int i = 0; i< N; i++)
vex[i].cost = 2000000000;
vector<vertex> v;
vex[N].level = vex[0].level - t;
vex[N].src = N;
vex[N].cost = 0;
edge* e = eg[N];
while(e != NULL)
{
int dst = e->dst;
int tempCost = e->cost + vex[N].cost;
bool tempBool = (vex[dst].level - vex[N].level >= 0 && vex[dst].level - vex[N].level <= M);
if(tempCost < vex[dst].cost && tempBool)
{
vex[dst].cost = tempCost;
v.push_back(vex[dst]);
push_heap(v.begin(), v.end(), cmp);
}
e = e->next;
}
while(v.size() > 0)
{
vertex tempV = v.front();
pop_heap(v.begin(),v.end(), cmp);
v.pop_back();
if(tempV.src == 0)
{
break;
}
int src = tempV.src;
edge* e = eg[src];
while(e != NULL)
{
int dst = e->dst;
int tempCost = e->cost + vex[src].cost;
bool tempBool = (vex[dst].level - vex[N].level >= 0 && vex[dst].level - vex[N].level <= M);
if(tempCost < vex[dst].cost && tempBool)
{
vex[dst].cost = tempCost;
v.push_back(vex[dst]);
push_heap(v.begin(), v.end(), cmp);
}
e = e->next;
}
}
if(minCost > vex[0].cost)
minCost = vex[0].cost;
}
cout << minCost;
return 0;
}