设计算法:dijkstra(最短路径)
题目大意:部落中每个人手里有一件物品都有一个给定的价值,这些物品可以用某些指定的其他物品加上一定的金币来交换,年轻的探险家为了以最少的金币获得国王手中的物品(也就是过往的女儿),注意部落有森严的等级制度,超过等级限制的两个人不能直接或者间接交易,年轻的探险家可以不受等级限制即第一次可以与任何人交易。
题目分析:建立最短路径算法的模型,将交换体系中的人看做是一个结点,结点之间的交换价值就是结点之间的权重,规定一个原本不存在的结点0使它到每个结点的权重为各个结点的自身价值,那么题目就变成了求结点0到结点1的最短路径(在等级限制下)
代码如下:
public class Main_1062 {
static int limt;
static int n;
static int[] p=new int[101];
static int[] r=new int[101];
static int[][] ex=new int[101][101];//ex[i][j]:表示用j替代i需要付出的金币
static int[] dis=new int[101];
static final int MAX=0x7FFFFFFF;
static boolean used[]=new boolean[101];
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
limt=in.nextInt();
n=in.nextInt();
int x=0;
for(int i=1;i<=n;i++){
p[i]=in.nextInt();
r[i]=in.nextInt();
x=in.nextInt();
for(int j=0;j<x;j++){
ex[i][in.nextInt()]=in.nextInt();
}
}
for(int i=1;i<=n;i++){
ex[i][0]=p[i];
}
solve();
}
static void dijkstra(){
Arrays.fill(dis, MAX);
dis[0]=0;//源结点
used[0]=false;
int x=1;int min=MAX;
for(int i=1;i<=n;i++){
min=MAX;
//第一步找到最小dis的结点
for(int j=0;j<=n;j++){
if(!used[j] && dis[j]<min){
min=dis[j];
x=j;
}
}
used[x]=true;
//更新与最小dis结点相邻且未被标记的结点的dis
for(int j=1;j<=n;j++){
if(!used[j] && ex[j][x]>0 && dis[j]>dis[x]+ex[j][x]){
dis[j]=dis[x]+ex[j][x];
//System.out.println("dis["+j+"]="+dis[j]);
}
}
}
}
//由于有了等级的限制,所以只有上面的是不够的,因为路径可能不通
static void solve(){
int min_dis=ex[1][0];
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(r[j]>=r[i] && r[j]<=r[i]+limt){//枚举出可用的结点
used[j]=false;
}else {
used[j]=true;
}
}
if(used[1]==false){
dijkstra();
}
if(dis[1]<min_dis){
min_dis=dis[1];
}
}
System.out.println(min_dis);
}
}