POJ 1062 昂贵的聘礼(最短路径.Dijkstra)

本文介绍了一种在特定等级限制下寻找最短路径的方法。考虑到酋长等级及其变化范围,通过枚举所有可能的等级区间来确定哪些节点可以参与交易。利用Dijkstra算法在过滤后的图中找到从起点到终点的最短路径。核心步骤包括数据读取、图的构建及执行Dijkstra算法。

因为有等级限制,关键是要枚举所有可能的情况。例如 M = 2, 酋长的等级是 4,那么所有能参与交易的人的等级要么是 2 ~ 4, 要么是 3 ~ 5, 要么是 4 ~ 6。只要把不能参加交易的人排除,算出最短路径即可。然后取各种情况中的最小值输出。

所以核心算法还是 Dijkstra。

#include<iostream>
#include<algorithm>
#include<climits>
#define FOR(i, N) for(int i = 1; i <= (N); i++)
using namespace std;

int cost[110][110];
int costFilt[110][110];
int rank[110];

void read(int N){					//读取数据
	FOR(i, N)
		FOR(j, N)
			cost[i][j] = -1;
	FOR(i, N){
		int X;
		cin >> cost[i][i] >> rank[i] >> X;
		while(X--){
			int j;
			cin >> j;
			cin >> cost[i][j];	
		}
	}
}

void build(int down, int up, int N){			//建立新图
	FOR(i, N)
		FOR(j, N)
			costFilt[i][j] = cost[i][j];
	FOR(i, N)
		if(rank[i] < down || rank[i] > up){
			FOR(j, N){
				costFilt[i][j] = -1;
				costFilt[j][i] = -1;
			}
		}
}

int dijkstra(int N){
	bool visit[110];
	int d[110];
	FOR(i, N){					//初始化
		visit[i] = false;
		d[i] = INT_MAX / 10;
	}
	FOR(i, N)
		d[i] = costFilt[i][i];
	FOR(i, N){					//标准的Dijkstra
		int MIN = INT_MAX;
		int index;
		FOR(i, N){				
			if(d[i] < MIN && !visit[i]){
				MIN = d[i];
				index = i;
			}
		}
		visit[index] = true;
		FOR(i, N){
			if(costFilt[i][index] != -1 && !visit[i]){
				d[i] = min(d[i], d[index] + costFilt[i][index]);
			}
		}
	}
	return d[1];
}

int main(){
	int M, N;
	cin >> M >> N;
	read(N);
	int MIN = INT_MAX;
	FOR(i, M + 1){						//枚举
		build(rank[1] - M + i - 1, rank[1] + i - 1, N);
		MIN = min(MIN, dijkstra(N));
	}
	cout << MIN << endl;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值