1. 程式人生 > >PAT (Advanced Level) Practice 1087 All Roads Lead to Rome (30 分)

PAT (Advanced Level) Practice 1087 All Roads Lead to Rome (30 分)

1、比較函式裡要考慮所有維數的優先順序
2、每個節點出佇列一次,防止相同最短路數量重複計數
因為最短路可能相同的時候,而happiness或average_happiness不同時會把每次記錄的num都扔到佇列裡,那麼num就會記重複,為了不重複,所以每個節點只能出佇列一次,而且出佇列保證是最優的那個節點,所以比較函式裡要考慮所有維數的優先順序。

#include<cstdio>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>
#include
<cstring>
#include<string> #include<iostream> using namespace std; const int N=200+5; struct Edge { int v,w,next; }edge[N*N]; struct Node { int u,dis,d,hap; bool operator<(const Node& p)const { if(dis!=p.dis) return dis>p.dis; if(hap!=p.hap)
return hap<p.hap; return d>p.d; } }; int a[N]; int head[N],edgetot; int dis[N],d[N],hap[N],num[N],pre[N],vis[N]; map<string,int> mp; map<int,string> rmp; void addEdge(int u,int v,int w) { edge[edgetot]={v,w,head[u]}; head[u]=edgetot++; }; void dijs(int s) { memset
(dis,0x3f,sizeof(dis)); priority_queue<Node> q; q.push({s,0,0,0}); dis[s]=0,d[s]=0,hap[s]=0,num[s]=1; while(!q.empty()) { Node u=q.top(); q.pop(); if(vis[u.u]) continue; vis[u.u]=1; for(int i=head[u.u];i!=-1;i=edge[i].next) { int v=edge[i].v,w=edge[i].w; if(dis[u.u]+w<dis[v]) { dis[v]=dis[u.u]+w; pre[v]=u.u; num[v]=num[u.u]; hap[v]=hap[u.u]+a[v]; d[v]=d[u.u]+1; q.push({v,dis[v],d[v],hap[v]}); } else if(dis[u.u]+w==dis[v]) { num[v]+=num[u.u]; if(hap[u.u]+a[v]>hap[v]) { pre[v]=u.u; hap[v]=hap[u.u]+a[v]; d[v]=d[u.u]+1; q.push({v,dis[v],d[v],hap[v]}); } else if(hap[u.u]+a[v]==hap[v]) { if(d[u.u]+1<d[v]) { pre[v]=u.u; d[v]=d[u.u]+1; q.push({v,dis[v],d[v],hap[v]}); } } } } } } void dfs(int u) { if(!pre[u]) { cout<<rmp[u]; return; } dfs(pre[u]); cout<<"->"<<rmp[u]; } int main() { int n,k; string u; cin>>n>>k>>u; int cnt=0; memset(head,-1,sizeof(head)); edgetot=0; mp[u]=++cnt,rmp[cnt]=u; for(int i=1;i<=n-1;i++) { cin>>u; mp[u]=++cnt,rmp[cnt]=u; cin>>a[mp[u]]; } while(k--) { string u,v; int w; cin>>u>>v>>w; addEdge(mp[u],mp[v],w); addEdge(mp[v],mp[u],w); } dijs(1); int ed=mp["ROM"]; printf("%d %d %d %d\n",num[ed],dis[ed],hap[ed],hap[ed]/d[ed]); dfs(ed); cout<<endl; return 0; }