题意:输入城市个数、路线个数、出发城市。城市的快乐值(权重),城市之间的路线花费(权重),求最短路线个数、最短路线花费,沿途城市快乐值之和、平均快乐值题目链接
思路:
原本想将城市名hash之后变量、发现数据范围过大、通过map实现城市下标以及下标与城市之间的映射、通过dijkstra算法,再通过dfs获取所求
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<iostream>
#define INF 100000
const int M=210;
using namespace std;
map<string,int> strtoint;
map<int,string> inttostr;
char start[5];
int Happy[M]={0},G[M][M],dis[M],order=0,Start,ROM;
bool visit[M]={false};
vector<int> pre[M];
int Code(string a){
if(strtoint.find(a)==strtoint.end())
{
strtoint[a]=order;
inttostr[order]=a;
return order++;
}else return strtoint[a];
}
void dijk(int v,int n)
{
fill(dis,dis+M,INF);
dis[v]=0;
for(int i=0;i<n;i++)
{
int u=-1,Min=INF;
for(int j=0;j<n;j++)
{
if(!visit[j]&&dis[j]<Min){
Min=dis[j];
u=j;
}
}
if(u==-1) return;
visit[u]=true;
for(int w=0;w<n;w++)
{
if(!visit[w]&&G[u][w]!=INF)
{
if(dis[u]+G[u][w]<dis[w]){
dis[w]=dis[u]+G[u][w];
pre[w].clear();
pre[w].push_back(u); //可能有多个前缀点
}else if(dis[u]+G[u][w]==dis[w]){
pre[w].push_back(u);
}
}
}
}
}
int leastcost=INF,maxHappy=-1,num=0;
double maxAvg;
vector<int> ans,tmp;
void dfs(int v,int n,int cost,int sumHappy)
{
tmp.push_back(v);
if(v==Start)
{
if(cost<leastcost)
{
leastcost=cost;
num=1;
maxHappy=sumHappy;
maxAvg=1.0*sumHappy/n;
ans=tmp;
}else if(cost==leastcost){
if(sumHappy>maxHappy){
maxHappy=sumHappy;
maxAvg=1.0*sumHappy/n;
ans=tmp;
}else if(maxHappy==sumHappy){
if(maxAvg<1.0*sumHappy/n){
maxAvg=1.0*sumHappy/n;
ans=tmp;
}
}
num++ ;
}
tmp.pop_back();
return ;
}
for(int i=0;i<pre[v].size();i++){
dfs(pre[v][i],n+1,cost+G[v][pre[v][i]],sumHappy+Happy[v]);
}
tmp.pop_back();
}
int main()
{
int n,m,val,dist,v,w;
string a,b;
cin>>n>>m>>start;
fill(G[0],G[0]+M*M,INF);
for(int i=0;i<n-1;i++) //注意,这里是n-1,不包含起始点
{
cin>>a>>val;
Happy[Code(a)]=val;
}
for(int i=0;i<m;i++)
{
cin>>a>>b>>dist;
v=Code(a);
w=Code(b);
G[v][w]=G[w][v]=dist;
}
Start=Code(start),ROM=Code("ROM");
dijk(Start,n);
dfs(ROM,0,0,0);
printf("%d %d %d %.0f\n",num,leastcost,maxHappy,maxAvg);
for(int i=ans.size()-1;i>=0;i--)
{
cout<<inttostr[ans[i]];
if(i!=0) cout<<"->";
}
return 0;
}