poj 1062 昂贵的聘礼 Dijkstra算法,中等难度,,,一道让我累觉不爱的题目
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 38474 | Accepted: 11132 |
Description
为了方便起见,我们把所有的物品从1开始进行编号,酋长的允诺也看作一个物品,并且编号总是1。每个物品都有对应的价格P,主人的地位等级L,以及一系列的替代品Ti和该替代品所对应的"优惠"Vi。如果两人地位等级差距超过了M,就不能"间接交易"。你必须根据这些数据来计算出探险家最少需要多少金币才能娶到酋长的女儿。
Input
Output
Sample Input
1 4 10000 3 2 2 8000 3 5000 1000 2 1 4 200 3000 2 1 4 200 50 2 0
Sample Output
5250
这道题真的很让我蛋疼。。我开始用的是记录路径,,发现无解,搞了一天,,然后就百度了题解。。发现自己真特么笨,蠢到家了,只要选择地位区间大小M的区间,然后进行Dijkstra求单源最短路径不就解决了吗,当然要注意的是,区间里一定要包含酋长的地位值。代码后面有测试数据。
看代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define INF 100000000 #define MAX 110 int graph[MAX][MAX] , map[MAX][MAX] , level[MAX] , dis[MAX]; bool visited[MAX]; int dijsktra(int n) { memset(visited,false,sizeof(visited)) ; for(int i = 1 ; i <= n ; ++i) { dis[i] = map[1][i] ; } dis[1] = map[1][1] ; int ans = dis[1] ; visited[1] = true ; for(int i = 0 ; i < n ; ++i) { int min = INF , index = 0 ; for(int j = 1 ; j <= n ; ++j) { if(!visited[j] && min>dis[j]) { min = dis[j]; index = j ; } } if(min == INF) { break ; } visited[index] = true ; for(int j = 1 ; j <= n ; ++j) { if(map[index][j] == INF) { continue ; } if(dis[j] > dis[index] + map[index][j]) { dis[j] = dis[index] + map[index][j] ; } } dis[index] += map[index][index]; ans = ans>dis[index]?dis[index]:ans ; } return ans ; } void init(int n) { for(int i = 0 ; i <= n ; ++i) { for(int j = 0 ; j <= i ; ++j) { map[i][j] = map[j][i] = INF ; } } } int main() { int m , n ; while(scanf("%d%d",&m,&n) != EOF) { for(int i = 0 ; i <= n ; ++i) { for(int j = 0 ; j <= i ; ++j) { graph[i][j] = graph[j][i] = INF ; } } for(int i = 1 ; i <= n ; ++i) { int p,x; scanf("%d%d%d",&p,&level[i],&x) ; graph[i][i] = p ; for(int j = 1 ; j <= x ; ++j) { int t , v ; scanf("%d%d",&t,&v) ; graph[i][t] = v ; } } int left=level[1]-m>0?level[1]-m:0 , right=left+m; int k = left , ans = INF ; while(k<=level[1]) { init(n) ; for(int i = 1 ; i <= n ; ++i) { if(level[i]>=left && level[i]<=right) { for(int j = 1 ; j <= n ; ++j) { map[i][j] = graph[i][j] ; } } } left++ , right++ ; int num = dijsktra(n) ; ans = ans>num?num:ans ; ++k ; } printf("%d\n",ans) ; } return 0 ; } /* 测试数据1: 1 4 10000 3 2 2 8000 3 5000 1000 2 1 4 200 3000 2 1 4 200 50 2 0 5250 测试数据2: 1 5 10000 3 4 2 3000 3 2000 4 2000 5 9000 8000 2 3 3 5000 4 2000 5 7000 5000 1 0 2000 4 1 5 1900 50 1 0 4000 测试数据3: 3 8 10000 3 6 2 3000 3 2000 4 2000 5 9000 7 1000 8 5008 8000 2 3 3 5000 4 2000 5 7000 5000 1 1 6 1000 2000 4 1 5 1900 50 1 0 5000 1 1 7 4007 2000 4 1 5 1900 80 3 0 2950 测试数据4: 1 10 1324 0 0 1234 0 0 255 0 0 67 0 0 56 0 0 2134 0 0 456 0 0 2345 0 0 67 0 0 6436 0 0 1324 测试数据5: 1 4 10000 3 2 2 1 3 3 1000 2 2 4 1 3 1 1000 3 1 4 2 100 4 0 105 测试数据6: 3 5 10000 3 4 2 3000 3 2000 4 2000 5 9000 8000 2 3 3 5000 4 2000 5 7000 5000 1 0 2000 4 1 5 1900 50 1 0 3950 测试数据7: 0 5 10000 3 4 2 3000 3 2000 4 2000 5 9000 8000 2 3 3 5000 4 2000 5 7000 5000 4 0 2000 3 1 5 1900 50 2 0 4000 */
与君共勉
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。