zoukankan      html  css  js  c++  java
  • 1087 All Roads Lead to Rome (30 分)(最短路径)

    直接用Dijkstra做

    #include<bits/stdc++.h>
    
    using namespace std;
    int n,m;
    map<string,int>si;
    map<int,string>is;
    const int N=251;
    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,0);
        fill(num,num+N,0);
        fill(past,past+N,0);
        fill(path,path+N,0);
        //for(int i=0;i<=n-1;i++) dis[i]=mp[v][i];
        dis[v]=0;
        num[v]=1;
        for(int i=0;i<n;i++){
            int u=-1;
            int minn=inf;
            for(int j=0;j<n;j++){
                if(!vis[j]&&minn>dis[j]){
                    u=j;
                    minn=dis[j];
                }
            }
            if(u==-1) return;
            vis[u]=true;
            for(int j=0;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]+1;//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]+1;
                            path[j]=u;
                        }
                        else if(w[u]+weight[j]==w[j]){
                            double uAvg=1.0*(w[u]+weight[j])/(past[u]+1);
                            double vAvg=1.0*w[j]/past[j];
                            if(uAvg>vAvg){//第三标尺:平均结点值
                                past[j]=past[u]+1;
                                path[j]=u;
                            }
                        }
                    }
                }
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        fill(mp[0],mp[0]+N*N,inf);
        fill(weight,weight+N,0);
        cin>>n>>m;
        string t;
        cin>>t;
        si[t]=0;
        is[0]=t;
        for(int i=1;i<=n-1;i++){
            string temp;
            cin>>temp;
            cin>>weight[i];
            si[temp]=i;
            is[i]=temp;
        }
        for(int i=0;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(0);
        int rom=si["ROM"];
        cout<<num[rom]<<" "<<dis[rom]<<" "<<w[rom]<<" "<<w[rom]/past[rom]<<endl;
        int tt=rom;
        vector<int>vec;
        while(tt!=0){
            vec.push_back(tt);
            tt=path[tt];
        }
        reverse(vec.begin(),vec.end());
        cout<<t<<"->";
        for(int i=0;i<vec.size();i++){
            if(i) cout<<"->";
            cout<<is[vec[i]];
        }
        cout<<endl;
        return 0;
    }

    用Dijkstra + dfs

    这样做会更好理解

    #include<bits/stdc++.h>
    
    using namespace std;
    int n,m;
    map<string,int>si;
    map<int,string>is;
    const int N=251;
    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=0;i<n;i++) dis[i]=mp[v][i];
        dis[v]=0;
        for(int i=0;i<n;i++){
            int u=-1;
            int minn=inf;
            for(int j=0;j<n;j++){
                if(!vis[j]&&minn>dis[j]){
                    minn=dis[j];
                    u=j;
                }
            }
            if(u==-1) return;
            vis[u]=true;
            for(int j=0;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=-1;
    int sum=0;
    int num=0;
    void dfs(int v)
    {
        if(v==0){
            sum++;
            t.push_back(v);
            int sumDis=0;
            int sumValue=0;
            sumValue=weight[t[t.size()-1]];
            for(int i=t.size()-2;i>=0;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=0;i<path[v].size();i++){
            dfs(path[v][i]);
        }
        t.pop_back();
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        fill(mp[0],mp[0]+N*N,inf);
        fill(weight,weight+N,0);
        cin>>n>>m;
        string t;
        cin>>t;
        si[t]=0;
        is[0]=t;
        for(int i=1;i<=n-1;i++){
            string temp;
            cin>>temp;
            cin>>weight[i];
            si[temp]=i;
            is[i]=temp;
        }
        for(int i=0;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(0);
        int rom=si["ROM"];
        dfs(rom);
        cout<<sum<<" "<<dis[rom]<<" "<<maxValue<<" "<<maxValue/(tt.size()-1)<<endl;
        reverse(tt.begin(),tt.end());
        for(int i=0;i<tt.size();i++){
            if(i) cout<<"->";
            cout<<is[tt[i]];
        }
        cout<<endl;
        return 0;
    }
  • 相关阅读:
    linux开发板出现Read-only file system的解决办法
    nginx源码分析之网络初始化
    nginx源码分析之hash的实现
    hdu4833 Best Financing(DP)
    PHP读取office word文档内容及图片
    nginx+uwsgi+bottle python服务器部署
    创建、托管和浏览文档
    python非官方扩展库
    simplexml_load_string 转换xml为数组
    PHPExcel 导出数据(xls或xlsx或csv)- 助手类(函数)
  • 原文地址:https://www.cnblogs.com/chenchen-12/p/10133552.html
Copyright © 2011-2022 走看看