直接用Dijkstra做

#include<bits/stdc++.h>

using namespace std;
int n,m;
map<string,int>si;
map<int,string>is;
const int N=;
int weight[N];
int mp[N][N];
const int inf=0x3f3f3f3f;
int dis[N];
bool vis[N];
int num[N];
int w[N];
int past[N];
int path[N];
void Dijkstra(int v)
{
fill(vis,vis+N,false);
fill(dis,dis+N,inf);
fill(w,w+N,);
fill(num,num+N,);
fill(past,past+N,);
fill(path,path+N,);
//for(int i=0;i<=n-1;i++) dis[i]=mp[v][i];
dis[v]=;
num[v]=;
for(int i=;i<n;i++){
int u=-;
int minn=inf;
for(int j=;j<n;j++){
if(!vis[j]&&minn>dis[j]){
u=j;
minn=dis[j];
}
}
if(u==-) return;
vis[u]=true;
for(int j=;j<n;j++){
if(!vis[j]&&mp[u][j]!=inf){
if(dis[j]>dis[u]+mp[u][j]){//第一标尺: 最短路径
dis[j]=dis[u]+mp[u][j];
num[j]=num[u];
w[j]=w[u]+weight[j];
past[j]=past[u]+;//s->j顶点个数等于s->u顶点个数+1
path[j]=u;//更新路径
}
else if(dis[j]==dis[u]+mp[u][j]){
num[j]+=num[u];
if(w[u]+weight[j]>w[j]){//第二标尺:结点的值
w[j]=w[u]+weight[j];
past[j]=past[u]+;
path[j]=u;
}
else if(w[u]+weight[j]==w[j]){
double uAvg=1.0*(w[u]+weight[j])/(past[u]+);
double vAvg=1.0*w[j]/past[j];
if(uAvg>vAvg){//第三标尺:平均结点值
past[j]=past[u]+;
path[j]=u;
}
}
}
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
fill(mp[],mp[]+N*N,inf);
fill(weight,weight+N,);
cin>>n>>m;
string t;
cin>>t;
si[t]=;
is[]=t;
for(int i=;i<=n-;i++){
string temp;
cin>>temp;
cin>>weight[i];
si[temp]=i;
is[i]=temp;
}
for(int i=;i<m;i++){
string a,b;
cin>>a>>b;
int num;
cin>>num;
int a1=si[a];
int b1=si[b];
mp[a1][b1]=mp[b1][a1]=num;
}
Dijkstra();
int rom=si["ROM"];
cout<<num[rom]<<" "<<dis[rom]<<" "<<w[rom]<<" "<<w[rom]/past[rom]<<endl;
int tt=rom;
vector<int>vec;
while(tt!=){
vec.push_back(tt);
tt=path[tt];
}
reverse(vec.begin(),vec.end());
cout<<t<<"->";
for(int i=;i<vec.size();i++){
if(i) cout<<"->";
cout<<is[vec[i]];
}
cout<<endl;
return ;
}

用Dijkstra + dfs

这样做会更好理解

#include<bits/stdc++.h>

using namespace std;
int n,m;
map<string,int>si;
map<int,string>is;
const int N=;
int weight[N];
int mp[N][N];
const int inf=0x3f3f3f3f;
int dis[N];
bool vis[N];
vector<int>path[N]; void Dijkstra(int v)
{
fill(vis,vis+N,false);
fill(dis,dis+N,inf);
for(int i=;i<n;i++) dis[i]=mp[v][i];
dis[v]=;
for(int i=;i<n;i++){
int u=-;
int minn=inf;
for(int j=;j<n;j++){
if(!vis[j]&&minn>dis[j]){
minn=dis[j];
u=j;
}
}
if(u==-) return;
vis[u]=true;
for(int j=;j<n;j++){
if(!vis[j]&&mp[u][j]!=inf){
if(dis[j]>mp[u][j]+dis[u]){
dis[j]=mp[u][j]+dis[u];
path[j].clear();
path[j].push_back(u);
}
else if(dis[j]==mp[u][j]+dis[u]){
path[j].push_back(u);
}
}
}
}
}
vector<int>t,tt;
int minDis=inf;
int maxValue=-;
int sum=;
int num=;
void dfs(int v)
{
if(v==){
sum++;
t.push_back(v);
int sumDis=;
int sumValue=;
sumValue=weight[t[t.size()-]];
for(int i=t.size()-;i>=;i--){
// sumDis+=mp[t[i+1]][t[i]];
sumValue+=weight[t[i]];
}
//注意这里不再需要管最短路径这个第一标尺 因为我们用Dijkstra求出来了
// 这几条路径
//的长度是一样的并且是都是最小的
if(maxValue<sumValue){
maxValue=sumValue;
tt=t;
}
else if(sumValue==maxValue){
double a=1.0*sumValue/tt.size();
double b=1.0*maxValue/t.size();
if(a<b){
tt=t;
}
} t.pop_back();
return;
}
t.push_back(v);
for(int i=;i<path[v].size();i++){
dfs(path[v][i]);
}
t.pop_back();
} int main()
{
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
fill(mp[],mp[]+N*N,inf);
fill(weight,weight+N,);
cin>>n>>m;
string t;
cin>>t;
si[t]=;
is[]=t;
for(int i=;i<=n-;i++){
string temp;
cin>>temp;
cin>>weight[i];
si[temp]=i;
is[i]=temp;
}
for(int i=;i<m;i++){
string a,b;
cin>>a>>b;
int num;
cin>>num;
int a1=si[a];
int b1=si[b];
mp[a1][b1]=mp[b1][a1]=num;
}
Dijkstra();
int rom=si["ROM"];
dfs(rom);
cout<<sum<<" "<<dis[rom]<<" "<<maxValue<<" "<<maxValue/(tt.size()-)<<endl;
reverse(tt.begin(),tt.end());
for(int i=;i<tt.size();i++){
if(i) cout<<"->";
cout<<is[tt[i]];
}
cout<<endl;
return ;
}

1087 All Roads Lead to Rome (30 分)(最短路径)的更多相关文章

  1. PAT甲级练习 1087 All Roads Lead to Rome (30分) 字符串hash + dijkstra

    题目分析: 这题我在写的时候在PTA提交能过但是在牛客网就WA了一个点,先写一下思路留个坑 这题的简单来说就是需要找一条最短路->最开心->点最少(平均幸福指数自然就高了),由于本题给出的 ...

  2. 【PAT甲级】1087 All Roads Lead to Rome (30 分)(dijkstra+dfs或dijkstra+记录路径)

    题意: 输入两个正整数N和K(2<=N<=200),代表城市的数量和道路的数量.接着输入起点城市的名称(所有城市的名字均用三个大写字母表示),接着输入N-1行每行包括一个城市的名字和到达该 ...

  3. [图的遍历&多标准] 1087. All Roads Lead to Rome (30)

    1087. All Roads Lead to Rome (30) Indeed there are many different tourist routes from our city to Ro ...

  4. 1087 All Roads Lead to Rome (30)(30 分)

    Indeed there are many different tourist routes from our city to Rome. You are supposed to find your ...

  5. 1087. All Roads Lead to Rome (30)

    时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Indeed there are many different ...

  6. PAT (Advanced Level) 1087. All Roads Lead to Rome (30)

    暴力DFS. #include<cstdio> #include<cstring> #include<cmath> #include<vector> # ...

  7. PAT 1087 All Roads Lead to Rome[图论][迪杰斯特拉+dfs]

    1087 All Roads Lead to Rome (30)(30 分) Indeed there are many different tourist routes from our city ...

  8. pat1087. All Roads Lead to Rome (30)

    1087. All Roads Lead to Rome (30) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yu ...

  9. PAT 1087 All Roads Lead to Rome

    PAT 1087 All Roads Lead to Rome 题目: Indeed there are many different tourist routes from our city to ...

  10. PAT甲级1087. All Roads Lead to Rome

    PAT甲级1087. All Roads Lead to Rome 题意: 确实有从我们这个城市到罗马的不同的旅游线路.您应该以最低的成本找到您的客户的路线,同时获得最大的幸福. 输入规格: 每个输入 ...

随机推荐

  1. Android学习笔记_44_apk安装、反编译及防治反编译

    一.APK安装 1.首先需要AndroidManifest.xml中加入安装程序权限: <!-- 安装程序权限 --> <uses-permission android:name=& ...

  2. BionicApi 学习笔记

    1.内存管理 malloc, realloc, free new, delete2.文件输入操作 fopen, fwrite, fputs, fputc, fprintf, fflush fread, ...

  3. java各种业务解决方案总结

    最近有点时间,突然感慨良多,感觉辛苦工作这么久什么都没有,总结了以前的工作,将接触的主要工具列出来,希望给大家解决问题做参考.相关工具都是实践检验过的 1.数据库 (1).内存数据库 redis (2 ...

  4. 【TOJ 3005】Triangle(判断点是否在三角形内+卡精度)

    描述 Given the coordinates of the vertices of a triangle,And a point. You just need to judge whether t ...

  5. 【模板】string中substr函数的运用

    substr有两种用法: 假设:string s = "0123456789" ;  //下标从0开始 ① string a = s.substr(5)               ...

  6. JDK1.8的安装

    [环境准备] OS版本:Windows10企业版.64位操作系统: JDK版本:jdk-8u131-windows-x64.exe [彻底卸载已安装的JDK] 01:卸载或删除JDK服务.有三种方式: ...

  7. 转:Zookeeper客户端Curator使用详解

    原文:https://www.jianshu.com/p/70151fc0ef5d Zookeeper客户端Curator使用详解 前提 最近刚好用到了zookeeper,做了一个基于SpringBo ...

  8. 快速解决Kali 更新失败问题

    Kali Linux 2018.4 初学者在安装完kali 系统后第一件事往往就是更新软件,但在更新过程中通常会出现各种各样的问题,比如更新提示不含有 'maincontrib' 组件,跳过配置文件 ...

  9. js-scroll判断页面是向上滚动还是向下滚动

    原理:那当前的scrollTop和之前的scrollTop对比 如果变大了,表示向下滚动(scrollTop值变大): 如果变小了,表示向上滚动(scrollTop值变小). 方法一:js代码: $( ...

  10. 方别《QQ群霸屏技术》,又见《QQ群建群细则》

    规则,时刻变动;QQ群系列,咱们再来一轮. QQ群霸屏技术,你说建群貌似很菜,大家仿佛都知道,其实只知其一不知其二. QQ群类别 群分类,常规的就以下几种. 普通群. 建群随意,偏个性化,一言不合就拉 ...