1003 Emergency(25分)

 

#include<iostream>
#include<vector>
const int INT_MAX = 2147483647;
typedef enum  { UNDISCOVERED, VISITED }VStatus;//顶点状态,未访问和已访问
template<typename Tv> struct Vertex {//城市
    Tv data;//消防队的数量,即顶点的数据
    VStatus status;//顶点状态
    Vertex(Tv const& d = (Tv)0) :
        data(d), status(UNDISCOVERED) {}
};
struct Edge {//路
    int weight;//路的长度,即图的权重
    Edge(int w) :
        weight(w) {}
};
template<typename Tv>
class GraphMatrix {//邻接矩阵
private:
    std::vector<Vertex<Tv>> V;//存放顶点,用以访问状态和消防队数量
    std::vector<std::vector<Edge*> > E;//存放路的指针,当不联通的时候是nullptr,联通则有指针
public:
    int currentCity, mustSavedCity;//我在接到警情时所在的城市,火灾的城市
    int miniPath;//最短路径
    int miniPathNumber;//最短路径数
    int teamNumber;//访问到的路径中团队数
    int maxTeamNumber;//最短路径中团队最多数
    int n;//结点数
    int e;//边数
    GraphMatrix() {
        n = e = miniPathNumber = teamNumber = currentCity = mustSavedCity = maxTeamNumber = 0;
        miniPath = INT_MAX;
    }
    ~GraphMatrix() {
        for (int j = 0; j < n; j++)
            for (int k = 0; k < n; k++)
                delete E[j][k];//逐条清除
    }
    int firstNbr(int i) {
        return nextNbr(i, n);
    }
    int nextNbr(int i, int j) {//找到i节点在j节点之后的下一个邻居(即存在路径)
        while ((-1 < j) && (!exists(i, --j)))
            ;
        return j;
    }
    int insert(Tv const& vertex) {//插入顶点,返回编号
        V.push_back(Vertex<Tv>(vertex));
        for (int j = 0; j < n; j++)
            E[j].push_back(nullptr);
        ++n;
        E.push_back(std::vector<Edge*>(n,nullptr));
        return n;
    }
    bool exists(int i, int j) {
        return (-1 < i) && (i < n) && (-1 < j) && (j < n) && (E[i][j] != nullptr);
    }
    void insert(int w, int i, int j) {//插入边的指针
        if (exists(i, j))
            return;
        E[i][j] = new Edge(w);
        ++e;
    }
    void DFS(int currentCity,int destination) {
        if (miniPath < destination)//当前路程比曾经最小路程长,舍弃该路径
            return;
        if (currentCity == mustSavedCity) {//找到节点
            teamNumber += V[currentCity].data;//加上目标城市的消防队数量
            if (destination < miniPath) {//找到新的最短路径,更新路径数量为一,更新消防队数量为当前路径数量
                miniPath = destination;
                miniPathNumber = 1;
                maxTeamNumber = teamNumber;
            }
            else if (destination == miniPath) {//找到另一条最短路径,路径数量加一,更新最大消防队数量
                miniPathNumber++;
                if (maxTeamNumber < teamNumber)
                    maxTeamNumber = teamNumber;
            }
            teamNumber -= V[currentCity].data;//退出目标城市,消防队数量为父节点的消防队数量
            return;
        }
        for (int w = firstNbr(currentCity); -1 < w; w = nextNbr(currentCity, w)) {//依次访问当前城市的邻居,一条路一条路找,看是否能到达目标城市
            V[currentCity].status = VISITED;//将当前城市设置为已访问,避免递归调用DFS()时重新访问当前节点,造成环路
            teamNumber += V[currentCity].data;//加上当前城市的消防队数量
            if (V[w].status == UNDISCOVERED)
                DFS(w, destination + E[currentCity][w]->weight);//递归调用DFS()函数,用来不断寻找下一个节点,判断下一个节点是不是目标节点
            V[currentCity].status = UNDISCOVERED;//退出当前城市
            teamNumber -= V[currentCity].data;//退出当前城市,消防队数量为父节点的消防队数量
        }
    }
};

int main() {
    GraphMatrix<int> map;
    int n, e;
    scanf("%d", &n);
    scanf("%d", &e);
    scanf("%d %d", &(map.currentCity), &(map.mustSavedCity));
    for (int i = 0,temp; i < n; ++i) {
        scanf("%d", &temp);
        map.insert(temp);
    }
    for (int k = 0, w, i, j; k < e; ++k) {
        scanf("%d %d %d", &i, &j, &w);
        map.insert(w, i, j);//2、5测试点一直错的原因 邻接矩阵的存储是关于斜对角线对称的
        map.insert(w, j, i);
    }
    map.DFS(map.currentCity, 0);
    printf("%d %d\n", map.miniPathNumber, map.maxTeamNumber);
    return 0;
}

1003 Emergency (25分) 

图的五种最短路径算法 

 二刷

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值