【PAT甲级】1087 All Roads Lead to Rome (30 分)(dijkstra+dfs或dijkstra+记录路径)
题意:
输入两个正整数N和K(2<=N<=200),代表城市的数量和道路的数量。接着输入起点城市的名称(所有城市的名字均用三个大写字母表示),接着输入N-1行每行包括一个城市的名字和到达该城市所能获得的快乐,接着输入M行每行包括一条道路的两端城市名称和道路的长度。输出从起点城市到目标城市"ROM"获得最大快乐且经历道路长度最短的道路条数和经历的道路长度和获得的快乐总数以及其中经过城市最少的那条路的到达每个城市所获得的平均快乐。下一行输出这条路的路径,城市名之间用"->"连接。
AAAAAccepted code:
//用pre数组记录最大快乐最小开销的道路路径会比用DFS暴力搜索快四到五倍🤔,记忆路径的版本以前博客写过一个用SPFA找最短路的版本,那个比较快
1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 string s; 5 map<string,int>mp; 6 map<int,string>rmp; 7 int w[207],vis[207]; 8 vector<pair<int,int> >edge[207]; 9 int dis[207]; 10 vector<int>path[207]; 11 int num[207],happy[207]; 12 int t; 13 vector<int>ans,res; 14 int length=1e9,average=0; 15 void dijkstra(int x){ 16 dis[x]=0; 17 num[x]=1; 18 priority_queue<pair<int,int> >pq; 19 pq.push({0,x}); 20 while(!pq.empty()){ 21 int now=pq.top().second; 22 pq.pop(); 23 if(vis[now]) 24 continue; 25 vis[now]=1; 26 for(int i=0;i<edge[now].size();++i){ 27 int v=edge[now][i].first; 28 if(vis[v]) 29 continue; 30 if(dis[now]+edge[now][i].second<dis[v]){ 31 dis[v]=dis[now]+edge[now][i].second; 32 pq.push({-dis[v],v}); 33 num[v]=num[now]; 34 path[v].push_back(now); 35 happy[v]=happy[now]+w[v]; 36 } 37 else if(dis[now]+edge[now][i].second==dis[v]){ 38 if(happy[v]<happy[now]+w[v]){ 39 happy[v]=happy[now]+w[v]; 40 path[v].push_back(now); 41 } 42 else if(happy[v]==happy[now]+w[v]) 43 path[v].push_back(now); 44 num[v]+=num[now]; 45 } 46 } 47 } 48 } 49 void dfs(int x){ 50 ans.push_back(x); 51 if(x==mp[s]){ 52 int sum=0; 53 for(int i=0;i<ans.size();++i) 54 sum+=w[ans[i]]; 55 if(sum==happy[t]) 56 if(length>ans.size()){ 57 length=ans.size(); 58 average=sum/(ans.size()-1); 59 res=ans; 60 } 61 ans.pop_back(); 62 return ; 63 } 64 for(int i=0;i<path[x].size();++i) 65 dfs(path[x][i]); 66 ans.pop_back(); 67 } 68 int main(){ 69 ios::sync_with_stdio(false); 70 cin.tie(NULL); 71 cout.tie(NULL); 72 int n,m; 73 cin>>n>>m; 74 cin>>s; 75 int cnt=0; 76 mp[s]=++cnt; 77 rmp[cnt]=s; 78 for(int i=1;i<n;++i){ 79 string x; 80 cin>>x; 81 mp[x]=++cnt; 82 rmp[cnt]=x; 83 if(x=="ROM") 84 t=cnt; 85 cin>>w[mp[x]]; 86 } 87 for(int i=1;i<=m;++i){ 88 string x,y; 89 cin>>x>>y; 90 int z; 91 cin>>z; 92 edge[mp[x]].push_back({mp[y],z}); 93 edge[mp[y]].push_back({mp[x],z}); 94 } 95 fill(dis+1,dis+1+n,1e9); 96 dijkstra(mp[s]); 97 dfs(t); 98 cout<<num[t]<<" "<<dis[t]<<" "<<happy[t]<<" "<<average<<"\n"; 99 for(int i=res.size()-1;i>=0;--i){ 100 if(i<res.size()-1) 101 cout<<"->"; 102 cout<<rmp[res[i]]; 103 } 104 return 0; 105 }
保持热爱 不懈努力
不试试看怎么知道会失败呢(划掉)
世上无难事 只要肯放弃(划掉)