题解[AHOI2002]哈利·波特与魔法石

题目传送门
这是一道很经典的最短路问题

因为数据范围较小,所以不用邻接表的SPFA也不会MLE

#include<bits/stdc++.h>
using namespace std;
int a[120][120];
//a[i][j]代表从i到j的路程(-1表示没路)
int h[8] = {0,2,6,4,8,6,10,14};
//h代表每种地形所需时间
queue<int> q; //队列
int s,e;//起点和终点
int dis[120]; //dis[i]代表点i到起点的最短时间
bool used[120] = {0}; //防止元素重复入队
int main(){
    memset(a,-1,sizeof(a));
    memset(dis,-1,sizeof(dis));
    bool flag;
    for(int i = 1;i<=7;i++){
        scanf("%d",&flag);
        if(flag==1)h[i]/=2;
    }//如果有魔法石则时间减半
    scanf("%d%d",&s,&e);
    int n;
    scanf("%d",&n);
    int ai,bi,ti;
    for(int i = 1;i<=n;i++){
        scanf("%d%d%d",&ai,&bi,&ti);
        a[ai][bi] = h[ti];
        a[bi][ai] = h[ti];
        //注意是无向图,要建立双向边(如果不建立双向边只有20分,我为此提交了4遍才过)
    }
    q.push(s);
    //起点入队
    dis[s] = 0;
    while(!q.empty()){ // 裸的SPFA
        int nw = q.front();
        for(int i = 1;i<=101;i++){
            if(a[nw][i]==-1)continue;
            int rd = dis[nw]+a[nw][i];//rd为经过nw到a的最短时间
            if(dis[i]==-1){ //如果这个点是第一次搜索到
                dis[i] = rd;
                q.push(i);
                used[i] = 1;
            }else{ //否则比较dis[i]和rd大小
                if(dis[i]<=rd)continue;
                dis[i] = rd;
                if(!used[i]){
                    q.push(i);
                    used[i] = 1;
                }
            }
        }
        q.pop();    
        used[nw] = 0;
    }
    printf("%d",dis[e]);
    //输出终点到起点的最短时间
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/LJA001100/p/10359572.html
今日推荐