zoukankan      html  css  js  c++  java
  • PAT甲级1018解法

    原题链接

    https://pintia.cn/problem-sets/994805342720868352/problems/994805489282433024

    思路

    本来准备用迪杰斯特拉算法先求出最短路径,再对每条最短路径进行深度遍历计算带出的车辆和带回的车辆进行比较。后来参考网上一位大神的做法,因为反正都要进行深度遍历,不如直接省去迪杰斯特拉算法,直接对所有路径进行深度遍历比较。这样做的话代码量一下子就减了不少。代码如下:

    代码

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    int C, N, S, M;
    vector<int> current;	//每个车站当前拥有车辆数
    vector<vector<int> > adjMatrix;	//邻接矩阵
    vector<bool> reach; //是否已经遍历过该点
    int minTake, minBack, minLen;	//最少带出的,最少带回的,最短路程
    vector<int> ans, temp;	//ans代表最终的最短路程,temp用于暂存每次遍历的路程并计算出ans
    
    void DFS(int s, int take, int back, int length)
    {
    	if (s == S)	//遍历到出问题的站点
    	{
    		if (length < minLen || (length == minLen && take < minTake) ||
    			(length == minLen && take == minTake && back < minBack))	//满足题目中给出的最短路径条件
    		{
    			ans = temp;	//记录当前经过的路程为结果路程
    			minLen = length;	//更新各项指标
    			minTake = take;
    			minBack = back;
    		}
    		return;
    	}
    	for (int i = 1; i < N + 1; i++)
    	{
    		if (reach[i] == false && adjMatrix[s][i] != 0)  //没有遍历过i点且s和i有路连接
    		{
    			reach[i] = true;
    			temp.push_back(i);	//将i点计入路程经过的点
    			int addTake = max(C / 2 - current[i], 0);	//需要增加的带出的车辆数量。如果i点数量比C/2大,则不用增加,如果比C/2下,则需要增加
    			if (back > 0)
    				addTake = max(0, addTake - back);	//如果有带回的,则和带出的相抵消。如果带回的比带出的多,则新增带出为0
    			int newBack = max(back + current[i] - C / 2, 0);	//新增带回的车数量
    			DFS(i, take + addTake, newBack, length + adjMatrix[s][i]);  //对i点进行深度遍历
    			reach[i] = false;   //遍历完成后删除i点的访问记录
    			temp.pop_back();	//弹出当前经过路径中的i点,准备遍历下一个点
    		}
    	}
    }
    int main()
    {
    	cin >> C >> N >> S >> M;
    	current.resize(N + 1);
    	adjMatrix.assign(N + 1, vector<int>(N + 1));
    	reach.assign(N + 1, false);
    	for (int i = 1; i < N+1; i++)
    	{
    		cin >> current[i];
    	}
    	for (int i = 0; i < M; i++)
    	{
    		int s1, s2, time;
    		cin >> s1 >> s2 >> time;
    		adjMatrix[s1][s2] = adjMatrix[s2][s1] = time;
    	}
    	minTake = minBack = minLen = 100000000;
    	DFS(0, 0, 0, 0);
    	printf("%d 0", minTake);
    	for (int i = 0; i < ans.size(); i++) {
    		printf("->%d", ans[i]);
    	}
    	printf(" %d", minBack);
    	return 0;
    }
    
  • 相关阅读:
    B 合约数
    Weekly Contest 80
    第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛
    2018年长沙理工大学第十三届程序设计竞赛
    通过 DDNS 解决宽带拨号 ip 变化问题
    frp 内网穿透的使用 和原理
    笔记本centos 取消 关闭盖子自动挂起
    centos7 pptp 安装
    linux 命令收集
    centos7 关闭防护墙
  • 原文地址:https://www.cnblogs.com/aopstudio/p/12254729.html
Copyright © 2011-2022 走看看