poj_1062

来源:互联网 发布:淘宝虚假订单没清洗 编辑:程序博客网 时间:2024/05/22 11:50

题干:

年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了,于是便向酋长去求亲。酋长要他用10000个金币作为聘礼才答应把女儿嫁给他。探险家拿不出这么多金币,便请求酋长降低要求。酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币。如果你能够弄来他的水晶球,那么只要5000金币就行了。"探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格。探险家于是又跑到其他地方,其他人也提出了类似的要求,或者直接用金币换,或者找到其他东西就可以降低价格。不过探险家没必要用多样东西去换一样东西,因为不会得到更低的价格。探险家现在很需要你的帮忙,让他用最少的金币娶到自己的心上人。另外他要告诉你的是,在这个部落里,等级观念十分森严。地位差距超过一定限制的两个人之间不会进行任何形式的直接接触,包括交易。他是一个外来人,所以可以不受这些限制。但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样。因此你需要在考虑所有的情况以后给他提供一个最好的方案。 
为了方便起见,我们把所有的物品从1开始进行编号,酋长的允诺也看作一个物品,并且编号总是1。每个物品都有对应的价格P,主人的地位等级L,以及一系列的替代品Ti和该替代品所对应的"优惠"Vi。如果两人地位等级差距超过了M,就不能"间接交易"。你必须根据这些数据来计算出探险家最少需要多少金币才能娶到酋长的女儿。 


思路:

(物品原价,主人级别)这个二元组作为一个节点
节点与节点之间根据替代品相连接(有向连接),连接的权值是出度节点物品优惠后的价格  
现在就是要找路径,从(酋长女儿,酋长),到每个节点,路径长度规定为每段路径的权值加上终节点的物品原价。并且要求,
每条路径中任意两个节点的主人级别差不超过M(通过维护当前路径中主任级别的最大值和最小值) 

把上面的路径做以下修订: 增加一个汇点X,X连接每一个节点,并且权值为每一个节点中的物品原价。 
这样,题目就变为找出原点到汇点X的最短路径(并且要求,每条路径中任意两个节点的主人级别差不超过M)

源代码:

#include<stdio.h>#include<stdlib.h>struct adjacent{    int weight;    int maxLevel;    int minLevel;};int goods[20][3];//goods[][0]存放原价 goods[][1]存放主人Level goods[][2]存放代替品数量 ,汇点level规定和酋长一样 int dijstra( struct adjacent arr[20][20], int M, int num ){//源点是0     int min,i,k,time;    //假设num-1号是汇点     //初始化源点到其余各点的路径中主人level的最大值和最小值    for( i=1; i<num; ++i ){        arr[0][i].maxLevel = goods[i][1] > goods[0][1] ?  goods[i][1] : goods[0][1];        arr[0][i].minLevel = goods[i][1] > goods[0][1] ?  goods[0][1] : goods[i][1];    }         for( time = 1; time < num; ++time ){        for( min = 9999999,i=1,k=0; i<num; ++i ){//寻找源点到其他所有点距离的最短值             if( arr[0][i].weight < min ){                min = arr[0][i].weight;                k = i;//记录下最短值的节点             }         }        printf("%d,%d\n",min,k);system("pause");                for( i=1; i<num; ++i ){//用这个最短值修订其他 (要考虑路径的最大级别差M)            if( arr[0][k].weight + arr[k][i].weight < arr[0][i].weight ){                if( goods[i][1] >= arr[0][k].minLevel && goods[i][1] <= arr[0][k].maxLevel ){                    arr[0][i].weight = arr[0][k].weight + arr[k][i].weight;                } else{                    if( abs( goods[i][1]-arr[0][k].minLevel )<=M && abs( goods[i][1]-arr[0][k].maxLevel )<=M ){                        arr[0][i].weight = arr[0][k].weight + arr[k][i].weight;                        if( goods[i][1] < arr[0][k].minLevel )                            arr[0][k].minLevel = goods[i][1];                        if( goods[i][1] > arr[0][k].maxLevel )                            arr[0][k].maxLevel = goods[i][1];                    }                }            }         }        if( k == num-1 )            return arr[0][num-1].weight;         arr[0][k].weight = 9999999;    }       }int main(){    int i, j, M, num, n, discount,result;    struct adjacent arr[20][20];    scanf("%d %d",&M,&num);        for( i=0; i<num; ++i ){        for( j=0; j<num; ++j ){            arr[i][j].weight = 9999999;        }    }//初始化邻接数组         for( i=0; i<num; ++i ){        scanf("%d %d %d",&goods[i][0],&goods[i][1],&goods[i][2]);        for( j=0; j<goods[i][2]; ++j ){            scanf("%d %d",&n, &discount);            arr[i][n-1].weight = discount;        }    }//建立邻接矩阵     for( i=0; i<num; ++i ){        arr[i][num].weight = goods[i][0];    }//向原图中添加汇点     goods[num][1] = goods[0][1];    ++num;    result = dijstra( arr, M, num );    printf("%d",result);    system("pause");}





0 0
原创粉丝点击