#include<bits/stdc++.h>
using namespace std;
map<string,int>city;
map<int,string>rcity;
map<int,vector<pair<int,int> > >edge;//对比string要比对比int慢很多,所以转换映射
int dis[207],path[207],hcount[207],happ[207],fstep[207],f[207];//源点到各点的最短距离,最短路径数量,快乐总数,快乐,经过点的个数,前一个点
int vis[207];
int main(){
    memset(dis,-1,sizeof(dis));
    memset(hcount,-1,sizeof(hcount));
    std::ios::sync_with_stdio(false);//关闭同步
    int n,k,i,d,s;
    string st,u,v;
    cin>>n>>k>>st;
    city[st]=0;//编号
    rcity[0]=st;//反编号
    happ[0]=0;
    dis[0]=0;
    hcount[0]=0;
    fstep[0]=0;
    path[0]=1;//init
    f[0]=0;
    for(i=1;i<n;++i){
        f[i]=i;
        cin>>u;
        rcity[i]=u;
        city[u]=i;
        cin>>happ[i];
    }
    for(i=0;i<k;++i){
        cin>>u>>v>>d;
        edge[city[u]].push_back(make_pair(city[v],d));//建邻接表
        edge[city[v]].push_back(make_pair(city[u],d));
    }
    s=0;
    vector<pair<int,int> >::iterator it;
    int next;
    while(s!=city["ROM"]){
        vis[s]=1;
        for(it=edge[s].begin();it!=edge[s].end();++it){
            next=it->first;
            if(dis[next]==-1||dis[next]>dis[s]+it->second){//松弛
                dis[next]=dis[s]+it->second;
                hcount[next]=hcount[s]+happ[next];
                path[next]=path[s];
                fstep[next]=fstep[s]+1;
                f[next]=s;
            }
            else{
                if(dis[next]==dis[s]+it->second){
                    path[next]+=path[s];
                    if(hcount[next]<hcount[s]+happ[next]){
                        hcount[next]=hcount[s]+happ[next];
                        fstep[next]=fstep[s]+1;
                        f[next]=s;
                    }
                    else{
                        if(hcount[next]==hcount[s]+happ[next]){
                            if(fstep[next]>fstep[s]+1){
                                fstep[next]=fstep[s]+1;
                                f[next]=s;
                            }
                        }
                    }
                }
            }
        }
        int mindis=-1,minnum;
        for(i=1;i<n;i++){
            if(dis[i]==-1)//如果当前边到不了初始点,直接pass
                continue;
            if(!vis[i]&&(mindis==-1||(dis[i]<mindis))){
                mindis=dis[i];
                minnum=i;
            }
        }
        s=minnum;//找到当前距离源点最近的一个点向下搜索
    }
    cout<<path[s]<<" "<<dis[s]<<" "<<hcount[s]<<" "<<hcount[s]/fstep[s]<<endl;
    int p=s;
    stack<int>ss;
    while(p){
        ss.push(p);
        p=f[p];
    }
    cout<<rcity[p];
    while(!ss.empty()){
        cout<<"->"<<rcity[ss.top()];
        ss.pop();
    }
    return 0;
}

/*#include<bits/stdc++.h>
using namespace std;
const int INF = 1e9 ;
typedef struct node{
    int v;//节点编号
    int cost;//边权值
};
int N;//城市数量
int K;//道路条数
string start;//起始点城市名字
int happy[207];//存放各个城市的快乐值
map<string,int>stringToInt;//城市名字->编号
map<int,string>intToString;//编号->城市名字
vector<node>graph[207];//邻接表
int d[207];//记录从起始城市到达点i的最少花费值
vector<int>pre[207];//记录前一个节点
vector<int>path,tempPath;
int optHappy=0;
double optAverageHappy=0;
int cnt=0;//记录最短路径条数
int inq[207];//记录节点是否在队列中
void spfa(int s){
    for(int i=0;i<N;++i)
        d[i]=INF;
    d[s]=0;
    queue<int>q;
    q.push(s);
    inq[s]=1;
    while(!q.empty()){
        int u=q.front();
        q.pop();
        inq[u]=0;
        for(int j=0;j<graph[u].size();++j){
            int v=graph[u][j].v;
            int cost=graph[u][j].cost;
            if(!v)
                continue;
            if(d[u]+cost<d[v]){
                d[v]=d[u]+cost;
                pre[v].clear();
                pre[v].push_back(u);
                if(!inq[v]){
                    q.push(v);
                    inq[v]=1;
                }
            }
            else if(d[u]+cost==d[v])
                pre[v].push_back(u);
        }
    }
}
void dfs(int nowVisit){
    if(!nowVisit){
        cnt++;
        tempPath.push_back(nowVisit);
        int happyValue=0;
        for(int i=tempPath.size()-2;i>=0;--i)
            happyValue+= happy[tempPath[i]];
        double averageHappyValue=1.0*happyValue/(tempPath.size()-1);
        if(happyValue>optHappy){
            optHappy=happyValue;
            optAverageHappy=averageHappyValue;
            path=tempPath;
        }
        else if(happyValue==optHappy&&averageHappyValue>optAverageHappy){
            optAverageHappy=averageHappyValue;
            path=tempPath;
        }
        tempPath.pop_back();
        return;
    }
    tempPath.push_back(nowVisit);
    for(auto&it:pre[nowVisit])
  dfs(it);
    tempPath.pop_back();
}
int main(){
    std::ios::sync_with_stdio(false);//关闭同步
    cin>>N>>K>>start;
    stringToInt[start]=0; //起始城市编号为0
    intToString[0]=start;
    string city;
    int happyness;
    for(int i=1;i<N;++i){
        cin>>city>>happyness;
        stringToInt[city]=i;
        intToString[i]=city;
        happy[i]=happyness;
    }
    string city1,city2;
    int cost;
    for(int i=0;i<K;++i){
        cin>>city1>>city2>>cost;
        int id1=stringToInt[city1];
        int id2=stringToInt[city2];
        node x,y;
        x.v=id2;
        x.cost=cost;
        y.v=id1;
        y.cost=cost;
        graph[id1].push_back(x);
        graph[id2].push_back(y);
    }
    int destination=stringToInt["ROM"];
    spfa(0);
    dfs(destination);
    cout<<cnt<<" "<<d[destination]<<" "<<optHappy<<" "<<(int)optAverageHappy<<endl;
    for(int i=path.size()-1;i>=0;--i) {
        cout<<intToString[path[i]];
        if(i)
            cout<<"->";
    }
    return 0;
}*/

//SPFA先处理再DFS

All Roads Lead to Rome(30)(MAP【int,string】,邻接表,DFS,模拟,SPFA)(PAT甲级)的更多相关文章

  1. [图的遍历&多标准] 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 ...

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

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

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

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

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

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

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

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

  6. 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 ...

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

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

  8. 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 ...

  9. PAT_A1087#All Roads Lead to Rome

    Source: PAT A1087 All Roads Lead to Rome (30 分) Description: Indeed there are many different tourist ...

随机推荐

  1. vscode 小笔记

    用户设置: { "git.ignoreMissingGitWarning": true, "workbench.statusBar.feedback.visible&qu ...

  2. gcc 4.8.5安装

    在利用张乐博士的最大熵模型工具包(Maximum Entropy Modeling Toolkit for Python and C++)和条件随机场的经典工具包CRF++(CRF++: Yet An ...

  3. Android学习路线01

    part1:Java 1.Java基础 2.Java面向对象 3.数组与集合,异常,常用类 4.Io流 5.多线程socket编程 6.数据库,网络传输,数据解析 part2:Android 1.An ...

  4. php中五种常见的设计模式

    设计模式 一书将设计模式引入软件社区,该书的作者是 Erich Gamma.Richard Helm.Ralph Johnson 和 John Vlissides Design(俗称 “四人帮”).所 ...

  5. linux导出Mysql数据sql脚本

  6. Xposed模块开发学习记录

    Xposed模块相关API可以参考在线文档: https://api.xposed.info/reference/packages.html     入门教程可以参考: https://github. ...

  7. 每天一个linux命令(12):nl命令

    版权声明更新:2017-05-16博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下面的mv命令. 2. ...

  8. 如何自动生成和安装requirements.txt依赖

    在查看别人的Python项目时,经常会看到一个requirements.txt文件,里面记录了当前程序的所有依赖包及其精确版本号.这个文件有点类似与Rails的Gemfile.其作用是用来在另一台PC ...

  9. jquery.cxSelect插件,城市没单位

    jquery.cxSelect插件,新增城市没单位也能显示出来的功能. 具体,请查看修改后的插件代码:(主要是FixNoUnit函数) /*! * jQuery cxSelect * @name jq ...

  10. 快速排序的JavaScript实现

    思想 分治的思想,将原始数组分为较小的数组(但没有像归并排序一样将它们分隔开). 主元选择: 从数组中任意选择一项作为主元,通常为数组的第一项,即arr[i]:或数组的中间项, arr[Math.fl ...