poj1062(迪杰斯特拉算法的变形应用)

1.看不出这题是最短路问题,可以用迪杰斯特拉算法。。。
2.物品交换还有等级限制,加大难度。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
#define INF 0x3f3f3f3
#define MAX 105
#define MIN(a,b) (a<b?a:b)
int sta[MAX];
int map_[MAX][MAX];
int graph[MAX][MAX];
int dis[MAX];
int vis[MAX];
int n;
int dijsktra()
{
    
    
    int v,min_,ans;
    for(int i=1; i<=n; i++)
    {
    
    
        vis[i]=0;
        dis[i]=map_[1][i];
    }
    ans=dis[1];//坑,要跳过第一个进行判断
    vis[1]=1;
    for(int i=0; i<n; i++)
    {
    
    
        min_=INF;
        for(int j=1; j<=n; j++)
        {
    
    
            if(!vis[j]&&min_>dis[j])
            {
    
    
                min_=dis[j];
                v=j;
            }
        }
        if(min_==INF)//不能省略,起先以为是优化程序。
        {
    
    
            break;
        }
        vis[v]=1;
        for(int j=1; j<=n; j++)
        {
    
    
            if(!vis[j]&&dis[j]>dis[v]+map_[v][j])
            {
    
    
                dis[j]=dis[v]+map_[v][j];
            }
        }
        dis[v]=dis[v]+map_[v][v];
        ans=MIN(ans,dis[v]);
    }
    return  ans;
}
int main()
{
    
    
    int m,p,l,x,t,v,left,right,ans;
    while(cin>>m>>n)
    {
    
    
        ans=INF;
        for(int i=1; i<=n; i++)
        {
    
    
            for(int j=1; j<=n; j++)
            {
    
    
                graph[i][j]=INF;
            }
        }
        for(int i=1; i<=n; i++)
        {
    
    
            cin>>p>>l>>x;
            sta[i]=l;
            graph[i][i]=p;
            for(int j=1; j<=x; j++)
            {
    
    
                cin>>t>>v;
                graph[i][t]=v;
            }
        }
        left=sta[1]-m>0?sta[1]-m:0;
        right=left+m;
        while(left<=sta[1])//判断是否超出区间
        {
    
    
            for(int i=1; i<=n; i++)
            {
    
    
                for(int j=1; j<=n; j++)
                {
    
    
                    map_[i][j]=INF;
                }
            }
            for(int i=1; i<=n; i++)
            {
    
    
                if(sta[i]>=left&&sta[i]<=right)
                {
    
    
                    for(int j=1; j<=n; j++)
                    {
    
    
                        map_[i][j]=graph[i][j];
                    }
                }
            }
            int dollar=dijsktra();
            ans=MIN(ans,dollar);
            left++;//---->枚举区间
            right++;
        }
        cout<<ans<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/mingjiweixiao/article/details/113850119