zoukankan      html  css  js  c++  java
  • PAT

    Nothing to fear


    种一棵树最好的时间是十年前,其次是现在!

    那些你早出晚归付出的刻苦努力,你不想训练,当你觉的太累了但还是要咬牙坚持的时候,那就是在追逐梦想,不要在意终点有什么,要享受路途的过程,或许你不能成就梦想,但一定会有更伟大的事情随之而来。 mamba out~

    2020.7.14


    人一我十,人十我百,追逐青春的梦想,怀着自信的心,永不言弃!

    Public Bike Management

    考点: Dijkstra求最短路,Dijkstra记录最短路径,dfs,阅读理解

    题目大意

    给定一个起点PBMC,和一个终点SP,求出从PBMC 到 Sp的最短路径(如果不止一条则都要记录下来),从中挑选出一条,从PBMC需要发送的车辆最少的那一条路径,如果遇到重复则输出需要将自行车返回回去的尽可能少的那一条(题目确保该路径唯一)。

    分析

    1.如何记录在Dijkstra中所求得得最短路径,由于Dijkstra时基于贪心思想当你要利用某一个顶点 x 去松弛其他顶点时,x之前得结点已经被确定,换句话说就是每当你确定一个点,这个点得前一个点一定已经被确定,虽然听起来像废话但是还是需要去好好考虑的!故我们可以用一个容器来存在某个点的前一个点来记录路径

    定义一个容器vector<int> pre[N]; 用于存放结点的所确定的前一个结点有哪些
    while(!q.empty())
    {
        int x = q.top().second;q.pop();
        if(vis[x])continue;
        vis[x] = 1;
        for(int i = 1;i <= n;i ++)
        {
            int y = i , w = e[x][i];
            if(dis[y] > dis[x] + w) // 更新 x -> y
            {
                pre[y].clear();
                pre[y].push_back(x);
                dis[y] = dis[x] + w;
                q.push({-dis[y] , y});
            }else if(dis[y] == dis[x] + w){
                pre[y].push_back(x);
            }
        }
    }
    

    2.得到路径之后需要对路径进行dfs检查所需要发送/放回都达到最优的那一条路!

    需要注意的点:

    • 认真读题
    • 如何记录Dijkstra的最短路径的结点需要熟记利用记录前一个结点的pre容器!

    完整代码

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    const int N = 1005;
    int Cmax , n , m , sp , mid , minsent = 0x3f, mintake = 0x3f;
    int e[N][N] , dis[N] , carry[N];
    bool vis[N];
    priority_queue<pair<int,int> > q;
    vector<int> pre[N] , path;
    void dfs(vector<int> tmp, int now)
    {
    	if(now == 0)
    	{
    		int need = 0 , back = 0;
    		for(int i = tmp.size() - 1;i >= 0;i --)
    		{
    			int id = tmp[i];
    			if(carry[id] > 0)
    				back += carry[id];
    			else{
    				if(back > (0 - carry[id]))
    					back += carry[id];
    				else{
    					need += (0 - carry[id] - back);
    					back = 0;
    				}
    			}
    		}
    		if(need < minsent){
    			minsent = need;
    			mintake = back;
    			path = tmp;
    		}
    		if(need == minsent && back < mintake)
    		{
    			mintake = back;
    			path = tmp;
    		}
    	}
    	for(int i = 0;i < pre[now].size();i ++)
    	{
    		tmp.push_back(now);
    		dfs(tmp, pre[now][i]);
    		tmp.pop_back();
    	}
    }
    void Dijkstra()
    {
    	memset(dis , 0x3f , sizeof dis);
    	memset(vis , 0 ,sizeof vis);
    	dis[0] = 0; // 规定PBMC 为顶点 0
    	q.push({0 , 0});
    	while(!q.empty())
    	{
    		int x = q.top().second;q.pop();
    		if(vis[x])continue;
    		vis[x] = 1;
    		for(int i = 1;i <= n;i ++)
    		{
    			int y = i , w = e[x][i];
    			if(dis[y] > dis[x] + w) // 更新 x -> y
    			{
    				pre[y].clear();
    				pre[y].push_back(x);
    				dis[y] = dis[x] + w;
    				q.push({-dis[y] , y});
    			}else if(dis[y] == dis[x] + w){
    				pre[y].push_back(x);
    			}
    		}
    	}
    	vector<int> t;dfs(t, sp);
    }
    int main()
    {
    	memset(e , 0x3f , sizeof e);
    	for(int i = 0;i <= n;i ++)e[i][i] = 0;
    	cin >> Cmax >> n >> sp >> m;
    	mid = Cmax / 2;
    	for(int i = 1;i <= n;i ++)
    		scanf("%d",&carry[i]) , carry[i] = carry[i] - mid;
    	int a, b ,c;
    	for(int i = 0;i < m;i ++)
    	{
    		scanf("%d %d %d", &a ,& b, &c);
    		e[a][b] = e[b][a] = c;
    	}
    	Dijkstra();
    	cout << minsent << " 0";
    	for(int i = path.size() - 1;i >= 0;i --)
    	{
    		printf("->%d", path[i]);
    	}
    	cout << " " << mintake << endl;
    	return 0;
    }
    
  • 相关阅读:
    爬取校园新闻首页的新闻的详情,使用正则表达式,函数抽离
    网络爬虫基础练习
    Mysql 使用 select into outfile
    Mysql 使用CMD 登陆
    使用Clean() 去掉由函数自动生成的字符串中的双引号
    Get Resultset from Oracle Stored procedure
    获取引用某个主键的所有外键的表
    Entity Framework 丢失数据链接的绑定,在已绑好的EDMX中提示“Choose Your Data Connection”
    添加MySql Metat Database 信息
    at System.Data.EntityClient.EntityConnection.GetFactory(String providerString)
  • 原文地址:https://www.cnblogs.com/wlw-x/p/13299200.html
Copyright © 2011-2022 走看看