zoukankan      html  css  js  c++  java
  • PAT

    Nothing to fear


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

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


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

    All Roads Lead to Rome

    考点: Dijkstra 求最短路 + dijkstra记录路径 + dfs + map映射

    题目大意

    给你一个起点,和固定终点求出,起点到终点的最短路径的条数和起点道终点的最短距离,找到开心值最大的路径,如果不唯一,则目标路径为开心值平均值最大的那一条路径。

    分析

    老套路了 就不分析了

    需要注意的点:

    完整代码

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <map>
    #include <vector>
    #include <queue>
    #include <cstring>
    
    using namespace std;
    const int N = 205;
    int n , k , weight[N] , key = 1;
    int e[N][N] , romid , dis[N] , vis[N];
    string start;
    map<string,int> m;
    map<int,string> ma;
    priority_queue<pair<int,int> > q;
    vector<int> pre[N] , path;
    /*
    输出内容:
    1. 最短路径的条数
    2. 最短路径的cost
    3. 所选出的路径的最大的开心值
    4. 选出路径的平均开心值
    5. 输出整条路经
    */
    int roadcnt , cost , maxhapp = -1 ,averhapp = 0;
    void dfs(int now,vector<int> tpath)
    {
    	if(now == m[start])
    	{
    		roadcnt++;
    		int happ = 0, len = tpath.size();
    		for(int i = 0;i < len;i ++)
    		{
    			happ += weight[tpath[i]];
    		}
    		int aver = happ / len;
    		if(happ > maxhapp)
    		{
    			maxhapp = happ;
    			path = tpath;
    			averhapp = aver;
    		}else if(happ == maxhapp && aver > averhapp)
    		{
    			path = tpath;
    			averhapp = aver;
    		}
    	}
    	for(int i = 0;i < pre[now].size();i++)
    	{
    		tpath.push_back(now);
    		dfs(pre[now][i] , tpath);
    		tpath.pop_back();
    	}
    }
    void Dijkstra(int s)
    {
    	memset(dis , 0x3f , sizeof dis);
    	memset(vis , 0 , sizeof vis);
    	dis[s] = 0;
    	q.push({0 , s});
    	while(!q.empty())
    	{
    		int x = q.top().second;q.pop();
    		if(vis[x])continue;
    		vis[x] = 1;
    		for(int i = 1;i < key;i ++)
    		{
    			int y = i, w = e[x][i];
    			if(vis[y])continue;
    			if(dis[y] > dis[x] + w)
    			{
    				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);
    			}
    		}
    	}
    }
    int main()
    {
    	memset(e , 0x3f , sizeof e);
    	cin >> n >> k >> start;
    	string s;int w;m[start] = key++;
    	for(int i = 1;i < n;i ++)
    	{
    		cin >> s >> w;
    		m[s] = key;ma[key] = s;
    		if(s == "ROM")romid = key;
    		weight[key++] = w;
    	}
    	string a , b;
    	for(int i = 0;i < k;i ++)
    	{
    		cin >> a >> b >> w;
    		int nx = m[a] , ny = m[b];
    		e[nx][ny] = e[ny][nx] = w;
    	}
    	Dijkstra(1);
    	dfs(romid , vector<int> ());
    	cout << roadcnt << " " << dis[romid] << " ";
    	cout << maxhapp << " " << averhapp << endl;
    	cout << start;
    	for(int i = path.size() - 1;i >=0 ;i --)
    	{
    		cout << "->" << ma[path[i]];
    	}
    	return 0;
    }
    
  • 相关阅读:
    Solaris 默认Shell 修改
    关系数组
    文件描述符 文件操作 <> open 文件句柄
    IO 双引号 输出 输入
    第五章答案
    子例程 subroutine
    钻石操作符
    花括号的使用 printf %${width}s , 否则会 去找 $widths
    print reverse <> 是打印全部的文件内容 ?
    hihoCoder#1239 Fibonacci
  • 原文地址:https://www.cnblogs.com/wlw-x/p/13304102.html
Copyright © 2011-2022 走看看