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;}