浙大 PAT 甲级 1087 All Roads Lead to Rome 深度优先搜索 DFS

PAT甲级练习题已经出现过无数次类似的题目了,都是:找路径、择优条件。都用深度优先搜索来解决,出现次数多了之后就属于简单题了。

#include<stdio.h>
#include<vector>
#include<map>
#include<string>
#include<memory.h>
using namespace std;

struct Edge
{
    int next;
    int cost;
};

map<int, string> num2name;
map<string, int> name2num;
vector<int> happinesses;
vector<Edge> edges[201];
bool mark[201];
vector<int> bestRoute;
int bestCost = 1000000;
int bestHappiness = 0;
int bestAns = 0;

void DFS(int start, int end, int happiness, int cost, vector<int> route)
{
    for (int i = 0; i < edges[start].size(); i++)
    {
        int nextNum = edges[start][i].next;
        int nextCost = edges[start][i].cost;

        if (mark[nextNum] != true && cost <= bestCost)
        {
            happiness += happinesses[nextNum];
            cost += nextCost;
            route.push_back(nextNum);
            mark[nextNum] = true;
            if (nextNum == end)
            {
                if ((cost < bestCost) ||
                    (cost == bestCost&&happiness > bestHappiness) ||
                    (cost == bestCost&&happiness == bestHappiness&&route.size() < bestRoute.size()))
                {
                    bestAns = (cost == bestCost) ? (bestAns + 1) : 1;
                    bestCost = cost;
                    bestHappiness = happiness;
                    bestRoute.clear();
                    bestRoute.assign(route.begin(), route.end());
                }
                else if (cost == bestCost)
                {
                    bestAns++;
                }
            }
            else
            {
                DFS(nextNum, end, happiness, cost, route);
            }
            happiness -= happinesses[nextNum];
            cost -= nextCost;
            route.pop_back();
            mark[nextNum] = false;
        }
    }
}

int main()
{
    memset(mark, 0, sizeof(bool) * 201);
    int N, K;
    char start[5];
    scanf("%d %d %s", &N, &K, start);
    name2num[start] = 0;
    num2name[0] = start;
    happinesses.push_back(0);
    for (int i = 1; i < N; i++)
    {
        char city[5];
        int h;
        scanf("%s %d", city, &h);
        name2num[city] = i;
        num2name[i] = city;
        happinesses.push_back(h);
    }
    for (int i = 0; i < K; i++)
    {
        char a[5], b[5];
        int cost;
        scanf("%s %s %d", a, b, &cost);
        Edge edge;
        edge.next = name2num[b];
        edge.cost = cost;
        edges[name2num[a]].push_back(edge);
        edge.next = name2num[a];
        edges[name2num[b]].push_back(edge);
    }
    vector<int> route;
    route.push_back(0);
    DFS(0, name2num["ROM"], 0, 0, route);

    printf("%d %d %d %d\n", bestAns, bestCost, bestHappiness, bestHappiness / (bestRoute.size() - 1));
    printf("%s", num2name[0].c_str());
    for (int i = 1; i < bestRoute.size(); i++)
    {
        printf("->%s", num2name[bestRoute[i]].c_str());
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值