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;
    }
    
  • 相关阅读:
    C++逐行读取文本文件的正确做法
    <Android Framework 之路>Android5.1 Camera Framework(一)
    zeromq-4.1.2在windows下的编译
    Duilib应用修改程序图标方法
    gdal集成kml库的做法
    使用DWR实现JS调用服务端Java代码
    DirectUI界面编程(六)实现右键弹出菜单
    如何设计系统的错误码及错误信息
    TCP协议格式
    UDP协议
  • 原文地址:https://www.cnblogs.com/aopstudio/p/12254729.html
Copyright © 2011-2022 走看看