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

题意:

有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;
}

 

posted @ 2018-06-19 10:27  seasonal  阅读(104)  评论(0)    收藏  举报