PATA1087_Dijkstra + DFS(难度:⭐️⭐️⭐️)

该程序通过Dijkstra算法找到最短路径,并利用深度优先搜索(DFS)寻找平均幸福感最高的旅行路线。它将地名转换为数字,构建图并计算最优路径。程序读取城市和边的输入,输出最幸福路径的相关信息,包括路径成本、起点到终点的距离、最大幸福感和平均幸福感。

这个题因为要求avgHappy所以必须要回溯,要用到DFS。

地名要转化为数字这样才方便使用图。

//7:30 ~ 
#include <bits/stdc++.h>
using namespace std;
const int maxn = 220;
const int INF = 999999999;
int G[maxn][maxn], happy[maxn], dis[maxn];
int n, k, name = -1, a, len, maxHappy = 0, cntCost = 0;
double avgHappy = 0.0;
string start;
bool vis[maxn];
vector<vector<int>> path;
vector<int> temp, ans;
unordered_map<string, int> stonum;
unordered_map<int, string> numtos;
void Dijkstra(int s) {
    fill (vis, vis + maxn, false);
    fill (dis, dis + maxn, INF);
    dis[s] = 0;
    for (int i = 0; i < n; i++) {
        int u = -1, MIN = INF;
        for (int j = 0; j < n; j++) {
            if (vis[j] == false && dis[j] < MIN) {
                u = j;
                MIN = dis[j];
            }
        }
        if (u == -1) return;
        vis[u] = true;
        for (int v = 0; v < n; v++) {
            if (G[u][v] != INF && vis[v] == false) {
                if (dis[u] + G[u][v] < dis[v]) {
                    path[v].clear();
                    path[v].push_back(u);
                    dis[v] = dis[u] + G[u][v];
                }
                else if (dis[u] + G[u][v] == dis[v])
                    path[v].push_back(u);
            }
        }
    }
}
void DFS (int s, int sumHap, int cnt) {
    temp.push_back(s);
    if (s == stonum[start]) {
        cntCost++;
        if (sumHap == maxHappy && (1.0 * sumHap) / cnt > avgHappy) {
            avgHappy = (1.0 * sumHap) / cnt;
            ans = temp;
        }
        else if (sumHap > maxHappy) {
            maxHappy = sumHap;
            avgHappy = (1.0 * sumHap) / cnt;
            ans = temp;
        }
        return;
    }
    for (int i = 0; i < path[s].size(); i++) {
        int now = path[s][i];
        DFS (now, sumHap + happy[now], cnt + 1);
        temp.pop_back();
    }
}
int main() {
    fill (G[0], G[0] + maxn * maxn, INF);
    string temp, c1, c2;
    cin >> n >> k >> start;
    path.resize(n);
    stonum[start] = ++name;
    numtos[name] = start;
    for (int i = 0; i < n - 1; i++) {
        cin >> temp >> a;
        stonum[temp] = ++name;
        numtos[name] = temp;
        happy[stonum[temp]] = a;
    }
    for (int i = 0; i < k; i++) {
        int u, v;
        cin >> c1 >> c2 >> len;
        u = stonum[c1]; v = stonum[c2];
        G[u][v] = G[v][u] = len;
    }
    Dijkstra(stonum[start]);
    DFS(stonum["ROM"], happy[stonum["ROM"]], 0);
    reverse(ans.begin(), ans.end());
    printf ("%d %d %d %d\n", cntCost, dis[stonum["ROM"]], maxHappy, (int)avgHappy);
    for (int i = 0; i < ans.size(); i++) {
        if (i != 0) printf ("->");
        printf ("%s", numtos[ans[i]].c_str());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值