POJ 1062 DijStra 变形 枚举
来源:互联网 发布:数控加工中心编程招聘 编辑:程序博客网 时间:2024/06/03 23:48
/*题目大意:这道题实际上就是图的最短路径问题解题思路:建图, 结点为每件物品,把探险者也看成一个入度为零的节点,是n + 1结点之一,探险者到其他物品的直接连线的权值为物品的原始价格,其他 i -> j的边的权值为探险者获得i后换j的优惠价格。应该注意的是,由于等级限制,如果你和level[1] - k级别的人交易过,那么你最多只能和level[1] - k + m进行交易,因此我们要对这m个等级范围进行枚举,每次枚举只考虑该等级范围内的点,并求出n + 1点到1点的最小值(最短路,dijkstra),再记录多次枚举得到的最小值,最后的最小值即为所求答案。注意点:1.代码中涉及到了不少的数组,所以对于某些有特定含义的数组一定要进行初始化,以免在后面的数值比较时出错2.在设置一个很大的数字时要小心,最好是不要设置为最大整型数Integer.MAX_VALUE,因为一旦它参与运算就会出现 不可预料的错误,如果它只是进行数值比较的话,那么是可以的3.这道题目解法很多,建图可以用邻接矩阵也可以用邻接表,求最短路径可以用Dijkstra 也可以用其他的方法(例如:spfa)**/#include <stdio.h>#include <iostream>using namespace std;#define INF 1000000int map[101][101];//matrix表示图的邻接矩阵【有向图】int level[101];//levelint dist[101];//distance从0到该点的权值int mark[101];//mark 标记是否可以和他进行交易int m;// level distanceint n;// goods numberint ans;//resultvoid dijstra(){ int i,j,k,start,min; ans=INF; for(k=0;k<=m;k++){//枚举等级差 for(i=1;i<=n;i++){ if(level[i]-level[1]<=k&&level[1]-level[i]<=m-k){ mark[i]=1;//表示可以进行交易 dist[i]=map[0][i]; }else{ mark[i]=0; dist[i]=INF; } } for(i=1;i<=n;i++){ start=1; min=INF; for(j=1;j<=n;j++){//得到距离最短的点 if(mark[j]==1&&dist[j]<min){//可以访问的点 中距离最近的 start=j; min=dist[j]; } } mark[start]=0;//将刚刚得到距离最短的点标记为不能访问 for(j=1;j<=n;j++){ //由于新点的加入,要修改距离值【从0开始到该点的最短距离】 if(mark[j]==1&&dist[j]>dist[start]+map[start][j]) dist[j]=dist[start]+map[start][j]; } } if(ans>dist[1]) ans=dist[1]; } cout<<ans<<endl;} int main(){ cin>>m>>n; int i,j,k,t; for(i=0;i<=n;i++) for(j=0;j<=n;j++) // map[i][j] = (i == j ? 0 : INF);//图的初始化,注意对角线初始化为0,从自己出发到自己的花费为0 map[i][j]=INF; for(i=1;i<=n;i++) { cin>>map[0][i]>>level[i];//价格和等级 cin>>t;//替代品总数 for(j=1;j<=t;j++) { //cin>>k>>map[k][i];出现Runtime Error cin>>k; cin>>map[k][i];//建立有权边 } } dijstra(); system("pause"); return 0;}