您的位置:首页 > 其它

POJ1062 昂贵的聘礼 单源最短路径变形 dijkstra算法

2014-05-19 22:00 411 查看
转自:http://blog.csdn.net/yangliuy/article/details/7173287

思路:以物品为结点,物品之间的优惠价格为边权值建图,酋长10000金币当做0号结点,题意就是求图中各结点到0号结点的最短路长度,再加上终点处物品的价值,恰好就是探险家经过这个物品买卖途径所需要付出的金钱。用dijkstra算法求出单源最短路径,从各个结点的最短路径中选出最短的那条就是答案。基本还是经典最短路问题,但做了一点小小变形主要是:

1 有结点等级限制,需要枚举等级

2 把终点的物品价值计入最短路径中去,并且找最小的最短路径输出

3 要注意是单向图,即物品替换关系是单向的

Source Code
Problem: 1062User: yangliuACMer
Memory: 300KTime: 32MS
Language: C++Result: Accepted
[cpp] view
plaincopy

#include <iostream>

#define MAXN 102

#define inf 100000000

typedef int elem_t;

using namespace std;

struct Thing{

int val;//该物品价值

int level;//该物品主人等级

int replacen;//替换品数量

} things[MAXN];

int m,n,nonum,noval,s,mat[MAXN][MAXN],dist[MAXN],lev[MAXN],levn;

int i,j,p,k;

int dijkstra(int n,elem_t mat[][MAXN],int s){

int v[MAXN], maxlev, minlev;

int ans = things[0].val;

//枚举等级

for(p = 0; p < levn; p++){

maxlev = lev[p];

minlev = lev[p]-m;

if(things[0].level < minlev || things[0].level > maxlev) continue;

for (i = 0 ;i < n ;i++)

dist[i] = inf,v[i] = 0;

for (dist[s] = 0,j = 0; j < n; j++){

for (k = -1,i = 0; i < n; i++)

if (!v[i] && (k == -1|| dist[i] < dist[k])&&(things[i].level >= minlev && things[i].level <= maxlev))

k=i;

for (v[k] = 1,i = 0 ;i < n; i++)

if (!v[i] && dist[k] + mat[k][i] < dist[i] && (things[i].level >= minlev && things[i].level <= maxlev))

dist[i] = dist[k] + mat[k][i];

}

//把终点的val计入最短路径中去,并且找最小的最短路径输出

for(j=0; j<n; j++)

dist[j] += things[j].val;

for(j=0; j<n; j++)

if(dist[j]<ans)

ans = dist[j];

}

return ans;

}

int main(){

//读入数据建图,邻接矩阵形式

cin>>m>>n;

for(i = 0; i < n; i++)

for(j = 0; j<n ; j++)

mat[i][j] = inf;

levn = 0;

for(i = 0; i < n; i++){

cin>>things[i].val>>things[i].level>>things[i].replacen;

lev[levn++] = things[i].level;//记录所有物品的等级

for(j = 0; j < things[i].replacen; j++){

cin>>nonum>>noval;

mat[i][nonum-1] = noval;//注意是单向图

}

}

cout<<dijkstra(n,mat,0)<<endl;

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: