poj1062

#include<iostream>
using namespace std;
#define Size 102

int INF = 0x7FFFFFFF;
int M,N;
//int P[Size]; //price
int L[Size]; //level
int dis[Size][Size];

int dist[Size];
int prev[Size];

int maxLevel = 0;
int minLevel = INF;
int minPrice = INF;

void Input()
{
    cin >> M >> N;
    for(int i=0;i<=N;i++){
        for(int j=0;j<=N;j++){
            dis[i][j] = INF;
        }
    }

    dis[0][0] = 0; //easy to forget!!!! important!
    
    for(int i=1;i<=N;i++)
    {
        int tnum;
        //cin >> P[i] >> L[i] >> tnum;
        cin >> dis[0][i] >> L[i] >> tnum;
        if(L[i] > maxLevel) maxLevel = L[i];
        if(L[i] < minLevel) minLevel = L[i];
        for(int j=1;j<=tnum;j++)
        {
            int tid;
            cin >> tid;
            cin >> dis[tid][i];
        }
    }
}
void printarray()
{
    for(int i=0;i<N+1;i++){
        for(int j=0;j<N+1;j++){
//            printf("%12d",dis[i][j]);
        }
//        printf("\n");
    }
}
int Dijkstra(int adventurerlevel,int leveldislimit,int *level, int source, int n, int *dist, int *prev, int dis[Size][Size])
//totally n dots! 0,1,2...n-1
{
    //bool *exist = new bool [n];
    bool exist[Size];
    for(int i=0;i<n;i++)
    {
        dist[i] = INF;
        exist[i] = 0;    
    }
    dist[source] = 0;

    int tmin = INF;
    int tnode;
    for(int j=0;j<n;j++){
        tmin = INF;
        for(int i=0;i<n;i++){
            if(!exist[i] && dist[i]<tmin){
                tmin = dist[i];
                tnode = i;
                //cout<<"t "<<tmin<<endl;
                //cout<<tnode<<endl;
            }
        }
        exist[tnode] = true;
        if(tmin == INF) break;

        //cout<<"tnode "<<tnode<<" le "<<level[tnode]<<endl;
        if(tnode!=0)
        if(adventurerlevel+leveldislimit<level[tnode]||adventurerlevel>level[tnode])
        {
            //important!!! if at current level not visitable!
            //a higher level point may have already been reached from a lower point and dist value changed!
            //so remove it!
            dist[tnode] = INF;
            continue;
        }
        //if(adventurerlevel>level[tnode]){
            //continue;
        //}

        for(int i=0;i<n;i++){
            if(!exist[i]){
                int tdis = dist[tnode]+dis[tnode][i];
                if(tdis<0) tdis=INF;
                if(tdis < dist[i]){
                    dist[i] = tdis;
                    prev[i] = tnode;
                }
            }
        }
    }    
    //delete exist;

    return dist[1];
}
void Solve()
{
    minPrice = dis[0][1];

    int alevel = 1;
    for(int alevel=minLevel;alevel<=maxLevel;alevel++){
        int p = Dijkstra(alevel, M, L, 0, N+1, dist, prev, dis); //totally n dots! 0,1,2...n-1
        //cout<<"level "<<alevel<<" "<<endl;
        if(p<minPrice) minPrice = p;
    }
}

void Output()
{
    cout << minPrice << endl;
}

int main(){
    Input();
    //printarray();
    Solve();
    Output();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值