题意:探险家需要不停的交换来获得物品,最终得到酋长的女儿,和地位低的人交易后不能在和地位高的人交易
分析:交易的顺序有要求,交易的物品也有先后关系。将所有物品抽象成图的点,则价值为带权边,因为交易有顺序,则可将图变为有向图,则本题变为有向无环图(价值交换后均升高,并且没有负权)中,求单源最短路径,可以使用Dijkstra算法
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int INF=0xfffffff;
int M;
int N;
int dist[105];
int map[105][105];
int max_lev[105],min_lev[105];
int min_cost;
bool visted[105];
struct Node{
int price;
int level;
int num;
};
struct Node node[105];
int MAX(int a,int b){
return a>b?a:b;
}
int MIN(int a,int b){
return a<b?a:b;
}
int ABS(int a){
return a<0?-a:a;
}
bool LeveTest(int a,int b){
return ABS(a-b)<=M?true:false;
}
void Dijkstra(){
int i,j,min,min_pos=0;
for(i=1;i<=N;i++){
min=INF;
for(j=1;j<=N;j++)
if(dist[j]<min&&!visted[j]&&LeveTest(max_lev[j],min_lev[j])){
min=dist[j];
min_pos=j;
}
visted[min_pos]=true;
min_cost=MIN(min_cost,dist[min_pos]+node[min_pos].price);
for(j=1;j<=N;j++){
if(!visted[j]&& map[min_pos][j]!=-1&&dist[j]>dist[min_pos]+map[min_pos][j])
dist[j]=dist[min_pos]+map[min_pos][j];
max_lev[j]=MAX(node[j].level,max_lev[min_pos]);
min_lev[j]=MIN(node[j].level,min_lev[min_pos]);
}
}
}
int main(){
int i,j,k;
// freopen("in.txt","r",stdin);
while(scanf("%d%d",&M,&N)!=EOF){
memset(map,-1,sizeof(map));
memset(visted,false,sizeof(visted));
for(i=1;i<=N;i++)
dist[i]=INF;
k=0;
for(i=1;i<=N;i++){
scanf("%d%d%d",&node[i].price,&node[i].level,&node[i].num);
for(j=1;j<=node[i].num;j++){
int v,pri;
scanf("%d%d",&v,&pri);
map[i][v]=pri;
}
}
max_lev[1]=min_lev[1]=node[1].level;
dist[1]=0; min_cost=node[1].price;
Dijkstra();
printf("%d\n",min_cost);
}
return 0;
}