您的位置:首页 > 编程语言 > C语言/C++

poj1062昂贵的聘礼有等级限制的最短路径

2015-06-14 00:43 288 查看
//主要问题是在最短路径过程中注意等级的差距

//第一次用的以当前起点为最大等级或者最小等级

//后来发现效率较低,考虑用minlevel和maxlevel存储

//那么要到达酋长点,其他等级必须在minlevel<=level<=maxlevel之间的才进行更新

//0ms 196K

#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
#include <queue>
using namespace std;
#define MAX_V  110
#define  INF 0x3f3f3f3f
static int M,N;//M表示的是等级差两个物品等级差大于M那么就不能到达
static int P,L,X;

static struct good
{
int p;
int l;
int x;
}Goods[300];

static struct edge
{
edge(int _t,int _c):to(_t),cost(_c)
{

}
int to,cost;
};
typedef pair<int,int>p;
static int V;
vector<edge>G[MAX_V];
static int d[MAX_V];
static int minlevel;
static int maxlevel;
static void addedge(int from,int to,int v)
{
G[from].push_back(edge(to,v));
}

static int dijkstra(int s)
{
int res = INF;
priority_queue<p,vector<p>,greater<p> >que;//从小到大
fill(d,d+V+1,INF);
d[s] = 0;
int level = Goods[s].l;
que.push(p(0,s));
res = Goods[s].p;
while(!que.empty())
{
p p0 = que.top();que.pop();
int v = p0.second;
if (d[v]<p0.first)
continue;
for (int i=0;i<G[v].size();++i)
{
edge e = G[v][i];
if (d[e.to]>d[v]+e.cost)
{
if (Goods[e.to].l<minlevel)//为最小等级的时候
continue;
if (Goods[e.to].l>maxlevel)//为最大等级的时候
continue;
d[e.to] = d[v] + e.cost;
que.push(p(d[e.to],e.to));
}
if (d[e.to]+Goods[e.to].p<res)
{
res = d[e.to] + Goods[e.to].p;
}
}
}
return res;
}
static void solve()
{
int ans = INF;
int qiuLevel = Goods[1].l;
//要到达酋长那么就应该在这个范围之内所有等级
for (int i = qiuLevel-M;i<=qiuLevel;++i ){
minlevel = i;
maxlevel = i+M;
int ret = dijkstra(1);
if(ans> ret)
ans = ret;
}
printf("%d\n",ans);
}

int main()
{
scanf("%d %d",&M,&N);
V= N;
for (int i=1;i<=N;++i)
{
scanf("%d %d %d",&Goods[i].p,&Goods[i].l,&Goods[i].x);
int t,val;
for (int j=0;j<Goods[i].x;++j)
{
scanf("%d %d",&t,&val);
addedge(i,t,val);
}
}
solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息