当前位置: 代码迷 >> 综合 >> PAT1087 All Roads Lead to Rome (30)(最短路径+dfs+回溯)
  详细解决方案

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

热度:22   发布时间:2024-01-16 13:19:16.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;
}

 

  相关解决方案