poj 1062

题意:难得的中文题

思路:dijkstra算法的运用  新源点合并到旧源点时,新源点到旧源点的边权的移交(也可理解为松弛)

实在是不想做这个题  抄了个代码  这个代码太完美了

  1 #include<iostream>   
  2 using namespace std; 
  3 
  4 const int inf=0x7fffffff;   //无限大  
  5   
  6 int M,N;//M为等级差,N为物品数目   
  7 int price[101][101];   //物品i在有第t号替代品情况下的优惠价pricr[t][i],当t=0时说明i无替代品,此时为原价
  8 int lv[101];   //第i号物品主人的等级lv[i]
  9 int x[101];//第i号物品的替代品总数x[i]   
 10   
 11 int dist[101];//最初的源点0到任意点i的最初距离(权值),相当于每个物品的原价   
 12   
 13 bool vist[101];   //记录点i是否已被访问
 14  
 15 /*Initial and Input*/  
 16 
 17 void data_init()   
 18 {   
 19     memset(price,0,sizeof(price));   
 20     memset(lv,0,sizeof(lv));   
 21     memset(dist,inf,sizeof(dist));   
 22     memset(vist,false,sizeof(vist));  
 23     
 24     cin>>M>>N;   
 25     for(int i=1;i<=N;i++)   
 26     {   
 27         cin>>price[0][i]>>lv[i]>>x[i];   //price[0][i]物品i无替代品时的原价
 28   
 29         for(int j=1;j<=x[i];j++)   
 30         {   
 31             int t,u;   //t替代品编号,u优惠价(临时变量)
 32             cin>>t>>u;
 33             price[t][i]=u;   //物品i在有第t号替代品情况下的优惠价,即点t到点i的权值
 34         }   
 35     }   
 36 }   
 37 
 38 /*Dijkstra Algorithm*/   
 39 
 40 int dijkstra()   
 41 {   
 42        
 43     int node;//记录与当前源点距离最短的点   
 44     int sd;//最短距离   
 45     int i,j;
 46   
 47     for(i=1;i<=N;i++)   
 48         dist[i]=price[0][i];  //假设最初的源点就是0点,初始化最初源点到各点的权值dist[i]
 49 
 50     for(i=1;i<=N;i++)   //由于1点是目标点,因此最坏的打算是进行n次寻找源点到其他点的最短路,并合并这两点(不再访问相当于合并了)
 51     {   
 52         node=0;   
 53         sd=inf;   
 54         for(j=1;j<=N;j++)   
 55         {   
 56             if(!vist[j] && sd>dist[j])   //在未访问的点中,寻找最短的一条
 57             {   
 58                 sd=dist[j];   
 59                 node=j;   //记录该点
 60             }   
 61         }   
 62         if(node==0)   //若node没有变化,说明所有点都被访问,最短路寻找完毕
 63             break;   
 64            
 65         vist[node]=true;   //记录node点已被访问
 66         for(j=1;j<=N;j++)   
 67         {   
 68             if(!vist[j] && price[node][j] > 0 && dist[j] > dist[node] + price[node][j])   //把未访问但与node(新源点)连通的点进行松弛
 69                 dist[j]=dist[node]+price[node][j];   
 70         }   
 71     }   
 72     return dist[1];   //返回当前次交易后目标点1在等级lv[i]约束下的最短距离
 73 }   
 74   
 75 int main()   
 76 {
 77     data_init();   //初始化并输入数据
 78    
 79     int temp_price;    //当前次交易后目标点1在等级lv[i]约束下的最少价格
 80     int maxlv;       //最大等级(酉长的等级不一定是最大的)
 81     int minprice=inf;    //最低价格(初始化为无限大)
 82    
 83     for(int i=1;i<=N;i++)   
 84     {   
 85         /*在等级限制下,寻找允许被当前点访问的点*/
 86            
 87         maxlv=lv[i];   //把当前物品的等级暂时看做最高等级
 88         for(int j=1;j<=N;j++)   //遍历其他各点
 89         {   
 90             if(lv[j]>maxlv || maxlv-lv[j]>M)   //当其它物品j的等级比当前物品高(保证单向性),或者两者等级之差超出限制M时
 91                 vist[j]=true;    //物品j则强制定义为“已访问”状态,不参与后续操作
 92             else  
 93                 vist[j]=false;   //否则物品j定义为“未访问”状态,参与后续操作
 94         }   
 95 
 96         temp_price=dijkstra();   //记录当前次交易后目标点1在等级lv[i]约束下的最短距离(最少价格)
 97 
 98         if(minprice>temp_price)   //寻找各次交易后的最少价格,最终确认最少价格
 99             minprice=temp_price;   
100     }   
101     cout<<minprice<<endl;   
102   
103     return 0;   
104 }  

 

posted @ 2014-06-05 17:18  _一千零一夜  阅读(135)  评论(0编辑  收藏  举报