POJ_1062_昂贵的聘礼(最短路)

/*
这道题关键是解决怎么存储的问题和那个等级限制的处理。把物品看成是N个点
N个点的d[]初始值便是他们的价值。

map[i][j];代表物品i和物品j进行交换需要的钱数。
dijkstra算法:每次选择d值最小的节点x;
具体解释见代码。
*/
# i

 1 # include <stdio.h>
 2 # include <string.h>
 3 # define inf 100000000
 4 int map[110][110];        //map[i][j]代表物品i与j交换的钱数;
 5 int value[110],level[110];//物品的价值,等级水平。
 6 int n,m,vis[110];         //vis用于标记是否访问过。
 7 int d[110];               //记录最小花费。
 8 int dijkstra(int x)
 9 {
10     int i,j,k,min;
11     memset(vis,0,sizeof(vis));
12     d[0]=0;vis[0]=1;//源点d赋值成0
13     for(i=1;i<=n;i++)
14         d[i]=map[0][i];//每个物品赋值成它的价值;
15     for(i=1;i<=n;i++) //循环n次肯定能找到最短路。
16     {
17         min=inf;
18         for(j=0;j<=n;j++) //寻找结点当中值最小的,记录下标和最小值。   
19         {
20             if(!vis[j] && d[j]<min)
21             {
22                 min=d[j];
23                 k=j;
24             }
25         }
26         if(min == inf) //说明没有连通的边,或者已经都找完
27 break; 28 vis[k]=1; //标记被访问过。 29 for(j=0;j<=n;j++)//进行一次修改结点值操作,修改成源节点和k结点中最小的那一个; 30 {// k件物品加交换钱数比j物品的价值小才交换,前提是在允许的等级之内。 31 if(!vis[j] && d[j]>d[k]+map[k][j] && level[k]<=x+m &&level[k]>=x) 32 d[j]=d[k]+map[k][j]; 33 } 34 35 } 36 return d[1];//n次修改完了之后,d[1]保存的就是结果。 37 } 38 int main() 39 { 40 int i,j,k,x,price,id; 41 while(scanf("%d%d",&m,&n) != EOF) 42 { 43 for(i=0;i<=100;i++) 44 { 45 map[i][i]=0; 46 for(j=i+1;j<=100;j++) 47 { 48 map[i][j]=map[j][i]=inf; 49 } 50 } 51 52 for(i=1;i<=n;i++) 53 { 54 scanf("%d%d%d",&value[i],&level[i],&x); 55 for(j=1;j<=x;j++) 56 { 57 scanf("%d%d",&id,&price); 58 map[id][i]=price; 59 } 60 } 61 for(i=1;i<=n;i++) 62 map[0][i]=value[i]; 63 level[0]=level[1]; 64 int low=level[1]-m; 65 int ans=inf; 66 for(i=low;i<=level[1];i++) 67 { 68 int temp=dijkstra(i); 69 if(temp<ans) 70 ans=temp; 71 } 72 73 printf("%d\n",ans); 74 } 75 return 0; 76 77 }

 

posted on 2013-08-15 11:20  随风浪子的博客  阅读(94)  评论(0编辑  收藏  举报

导航