POJ1062:最短路

POJ1062

题解:

  • 如果a可以代替b,那么就连一条从a到b的边,权值为用b代替a,a需要的价格。

  • 再加一个点n+1,n+1连接所有点,权值为旅行家直接花钱的价格

  • 最后求的便是从n+1到1的最短路,并且路上结点的权值差绝对值小于等于M

  • 一开始我是记录路径,保存以前路上的等级最大值和最小值,但是行不通。后来参考了百度,原来可以枚举区间。枚举的区间必须包括酋长,设酋长等级为level,则区间为[level-M,level+M],但是还不行,因为中间可能会有等级差大于M,所以区间枚举为[level-M,level],[level-M+1,level+1]……[level,level+M]。然后Dijkstra。

代码:


#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
int const inf = 0x7f7f7f7f;
int const N = 100 + 10;
int m,n,w[N],dis[N];
struct Edge
{
	int to,dist;
};
vector<Edge>G[N];
void Init(){
	for(int i=1;i<=n+1;i++)	G[i].clear();
	for(int i=1;i<=n;i++){
		int p,l,x;
		scanf("%d%d%d",&p,&l,&x);
		w[i] = l; 
		G[n+1].push_back((Edge){i,p});
		for(int j=0;j<x;j++){
			int t,v;
			scanf("%d%d",&t,&v);
			G[t].push_back((Edge){i,v});
		}
	}
}
struct Node
{
	int u,len;
	Node(){};
	Node(int uu,int le):u(uu),len(le){};
	bool operator < (const Node &e) const{
		return len < e.len;
	}
};
priority_queue<Node>q;
void Dijkstra(int l,int r){
	for(int i=0;i<=n+1;i++)	dis[i] = inf;
	dis[n+1] = 0;
	q.push(Node(n+1,0));  
	while(!q.empty()){
		Node p = q.top();	q.pop();
		int u = p.u,	len = p.len;
		if(dis[u] < len)	continue;
		for(int i=0;i<G[u].size();i++){
			Edge e = G[u][i];
			if(l <= w[e.to] && w[e.to] <= r){
				if(dis[e.to] > dis[u] + e.dist){
					dis[e.to] = dis[u] + e.dist;
					q.push(Node(e.to,dis[e.to]));
				}
			}
		}
	}
}
int main(){
	while(~scanf("%d%d",&m,&n)){   
		Init();     
		int ans = inf;
		for(int i=w[1]-m;i<=w[1];i++){
			Dijkstra(i,i+m);
			ans = min(ans,dis[1]);
		}
		printf("%d\n",ans);
	}

}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值