您的位置:首页 > 其它

POJ-1062 昂贵的聘礼

2016-02-18 17:28 429 查看
一开始想用动态规划做,但是发现有可能有环,这样需要做许多额外的处理工作,所以使用dijkstra求单元最短路。

建图使用可交换的优惠物品做有向图,如A需要 B加上一个优惠价格valueB来交换,那么就连接一条B到A的有向边,权值为valueB。探险家设置为0点,对每个物品都有一个有向边,权值为物品的价格。

考虑到dijkstra并不好加入等级的限制,那么可以取巧地使用枚举来枚举等级范围,不满足范围的点不予考虑即可。

#include<stdio.h>
#include<stdlib.h>

int map[101][101];
int p[101], l[101], x[101];
int n, m;
const int maxint = 20000000;

int dijkstra(int min){
short flag[101];
int i, j, step, minl, tmp;  //"step" means the recent point in the shortest set
int len[101];   //the length of the path
for (i = 0; i <= n; i++){
flag[i] = 0;
len[i] = maxint;
}
len[0] = 0;
flag[0] = 1;
i = 0;
step = 0;
while (i < n){
minl = maxint;
i++;
for (j = 1; j <= n; j++)
if ((l[j] >= min)&&(l[j] <= min + m)&&(map[step][j] + len[step] < len[j])) len[j] = map[step][j] + len[step];
for (j = 1; j <= n; j++)
if ((!flag[j])&&(len[j] < minl)){
minl = len[j];
tmp = j;
}
flag[tmp] = 1;
step = tmp;
}
return len[1];
}

int main(){
int i, j, t, v, maxl, tmp;
maxl = maxint;
scanf("%d %d", &m, &n);
for (i = 0; i <= n; i++)
for (j = 0; j <= n; j++)
map[i][j] = maxint;
for (i = 1; i <= n; i++){
scanf("%d %d %d", &p[i], &l[i], &x[i]);
map[0][i] = p[i];
for (j = 1; j <= x[i]; j++){
scanf("%d %d", &t, &v);
map[t][i] = v;
}
}
for (i = 1; i <= n; i++){
tmp = dijkstra(l[i]);
//printf("tmp = %d\n", tmp);
if (maxl > tmp) maxl = tmp;
}
printf("%d\n", maxl);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: