直接用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. 微信小程序分包加载

    分包加载 某些情况下,开发者需要将小程序划分成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载. 在构建小程序分包项目时,构建会输出一个或多个功能的分包,其中每个分包小程序必定含有一个主 ...

  2. unity3D引擎:2D游戏自动瞄准算法实现

    转:http://blog.csdn.net/naitu/article/details/39555373 在很多飞行射击类游戏里,都有敌人向玩家自动瞄准并开火的功能.在这里本人用unity3D引擎新 ...

  3. 有连接服务&无连接服务

    面向连接的服务 通信双方在通信时要事先建立一条通信线路,其过程包括建立连接.使用链接.释放链接三个过程 如: TCP 电话 面向无连接的服务 通信双方不需要事先建立一条通信线路,而是把每个带有目的选址 ...

  4. 【oracle使用笔记2】使用Oracle数据库遇到的若干问题总结

    一. 关于Oracle 11g数据库在查询表中数据显示中文乱码问题 [描述]本人一开始使用的Oracle是11g版本的,用PLSQL一次查询表中的数据时出现了中文显示乱码,为此搜了许多解决办法,最终通 ...

  5. xcode7--iOS开发---将app打包发布至app store

    时隔3个月再次接触应用打包,又是一顿折腾 说说这次的感受吧: 变得是打包时间减少到4小时(其中大部分时间还是xcode7或者是iOS9的原因),不变的是还是一如既往的坑!! 好了,废话不多说,下面讲讲 ...

  6. 修改状态栏,电池,wifi的颜色为白色

    修改状态栏,电池,wifi的颜色为白色 在info里面设置View controller-based status bar appearance,为no

  7. 重写Alert和confirm方法去除地址显示

    //重写alert方法,去掉地址显示window.alert = function(name){var iframe = document.createElement("IFRAME&quo ...

  8. 2018 Wannafly summer camp Day8--区间权值

    区间权值 小Bo有\(n\)个正整数\(a_1\)--\(a_n\),以及一个权值序列\(w_1\)--\(w_n\),现在她定义\(f(l,r)=(\sum_{i=l}^r a_i^2) *w_{r ...

  9. vue js 保留小数

    toFixed(number,fractionDigits ){ //number 保留小数数 //fractionDigits 保留小数位数 var times = Math.pow(10, fra ...

  10. vue 导出流文件excel

    第一种方法:需要设置响应类型,这里还需要安装 npm install js-file-download --save ,然后引用 var fileDownload = require('js-file ...