PAT1087 All Roads Lead to Rome (30)(最短路径+dfs+回溯)

48 篇文章 0 订阅

题意:

有N个城市,M条无向边,从某个给定的起始城市出发,前往名为ROM的城市。每个城市(除了起始城市)都有一个点权(称为幸福值),和边权(每条边所需的花费)。求从起点到ROM所需要的最少花费,并输出其路径。如果路径有多条,给出幸福值最大的那条。如果仍然不唯一,选择路径上的城市平均幸福值最大的那条路径。

思路:

这种题,如果简单一点,要求没那么多的情况,可以直接在dijkstra中写用dp的思想顺便求出幸福值最大的情况,但是这题还有平均幸福值,所以只能先用dijkstra求出最小花费的所有路径,再利用dfs回溯进行求解。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=250;
int road[maxn][maxn];
int cost[maxn];
int dis[maxn];
bool vis[maxn];
int n,m;
map<string,int> m1;
map<int,string> m2;
vector<int> pre[maxn];
vector<int> temppath,path;
int maxhap,pathnum;
double avghap;

void dijkstra(int start){
    fill(dis,dis+maxn,inf);
    fill(vis,vis+maxn,false);
    dis[start]=0;
    for(int i=0;i<n;i++){
        int u=-1,minn=inf;
        for(int j=0;j<=n;j++){
            if(!vis[j]&&dis[j]<minn){
                minn=dis[j];
                u=j;
            }
        }
        vis[u]=true;
        for(int v=0;v<=n;v++){
            if(!vis[v]){
                if(dis[v]>dis[u]+road[u][v]){
                    dis[v]=dis[u]+road[u][v];
                    pre[v].clear();
                    pre[v].push_back(u);
                }else if(dis[v]==dis[u]+road[u][v]){
                    pre[v].push_back(u);
                }
            }
        }

    }
}

void dfs(int v){
    temppath.push_back(v);
    if(v==1){
        int sum=0;
        for(int i=0;i<temppath.size();i++){
            sum+=cost[temppath[i]];
        }
        double avg=(double)sum/(temppath.size()-1);
        if(sum>maxhap){
            maxhap=sum;
            path=temppath;
            avghap=avg;
        }else if(sum==maxhap&&avg>avghap){
            avghap=avg;
            path=temppath;
        }
        pathnum++;
        return;
    }
    for(int i=0;i<pre[v].size();i++){
        int u=pre[v][i];
        dfs(u);
        temppath.pop_back();
    }
}

int main(){
    string start,temp;
    cin>>n>>m>>start;
    m1[start]=1;
    m2[1]=start;
    for(int i=1;i<n;i++){
        cin>>temp>>cost[i+1];
        m1[temp]=i+1;
        m2[i+1]=temp;
    }
    fill(road[0],road[0]+maxn*maxn,inf);
    string sa,sb;
    int d;
    for(int i=0;i<m;i++){
        cin>>sa>>sb>>d;
        road[m1[sa]][m1[sb]]=d;
        road[m1[sb]][m1[sa]]=d;
    }
    dijkstra(1);
    dfs(m1["ROM"]);
    printf("%d %d %d %d\n", pathnum, dis[m1["ROM"]], maxhap, (int)avghap);
	for (int i = path.size() - 1; i >= 1; i--) {
		cout << m2[path[i]] << "->";
	}
	cout << "ROM" << endl;
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MATLAB中可以使用Mapping Toolbox中的函数对shp文件进行最短路径规划。下面是一个简单的示例代码,展示如何使用Dijkstra算法计算两点之间的最短路径。 首先,需要使用shaperead函数读取shp文件,并获取道路网络的节点和边信息。 ```matlab % 读取shp文件 roads = shaperead('roads.shp'); % 获取节点和边信息 nodes = [roads.X', roads.Y']; edges = delaunayTriangulation(nodes); ``` 然后,可以使用shortestpath函数计算两个节点之间的最短路径。这里使用Dijkstra算法作为最短路径计算的方法。 ```matlab % 计算最短路径 startNode = 1; endNode = 100; path = shortestpath(edges, startNode, endNode); ``` 最后,可以使用plot函数将最短路径可视化。 ```matlab % 可视化最短路径 figure hold on plot(nodes(:,1), nodes(:,2), 'b.') plot(nodes(path,1), nodes(path,2), 'r-', 'LineWidth', 2) plot(nodes(startNode,1), nodes(startNode,2), 'go', 'MarkerSize', 10) plot(nodes(endNode,1), nodes(endNode,2), 'ro', 'MarkerSize', 10) axis equal ``` 完整的代码如下: ```matlab % 读取shp文件 roads = shaperead('roads.shp'); % 获取节点和边信息 nodes = [roads.X', roads.Y']; edges = delaunayTriangulation(nodes); % 计算最短路径 startNode = 1; endNode = 100; path = shortestpath(edges, startNode, endNode); % 可视化最短路径 figure hold on plot(nodes(:,1), nodes(:,2), 'b.') plot(nodes(path,1), nodes(path,2), 'r-', 'LineWidth', 2) plot(nodes(startNode,1), nodes(startNode,2), 'go', 'MarkerSize', 10) plot(nodes(endNode,1), nodes(endNode,2), 'ro', 'MarkerSize', 10) axis equal ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值