PAT (Advanced Level) Practice 1087 All Roads Lead to Rome (30 分)
阿新 • • 發佈:2018-11-29
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;
}