1111 Online Map (30 分)
这是真的水,就是写起来烦(摊手)。
题意
给定一个图、一个起点和一个终点,求一条距离最短的路径,如果有多条距离最短的路径,从中选择时间最短的一条,数据保证唯一性;再求一条时间最少的路径,如果有多条时间最少的路径,从中选择路径上顶点个数最少的一条,数据保证唯一性。如果距离最短和时间最少的是同一条路径,那么合并着输出。
注意点
- 注意题意,有多条最短距离路径和多条最少时间路径的处理不是对称的!当有多条最短距离路径时,应当选择时间最少的路径;而当有多条最少时间路径时,应当选择顶点个数最少的路径!
- 建议使用vector来存放最优路径,以方便对两条最优路径进行相等性的比较。
const int N=510;
struct Node
{
int v;
int len,tim;
};
vector<Node> g[N];
vector<int> dispath,timpath;
int dist1[N],dist2[N];
bool vis[N];
int pre[N];
int f[N];
int num[N];
int n,m,st,ed;
void dijkstra1(int dist[])
{
memset(dist,0x3f,4*N);
memset(vis,0,sizeof vis);
memset(pre,-1,sizeof pre);
dist[st]=0;
f[st]=0;
priority_queue<PII,vector<PII>,greater<PII>> heap;
heap.push({0,st});
while(heap.size())
{
int t=heap.top().se;
heap.pop();
if(vis[t]) continue;
vis[t]=true;
for(int i=0;i<g[t].size();i++)
{
int j=g[t][i].v,w=g[t][i].len,cost=g[t][i].tim;
if(dist[j] > dist[t] + w)
{
dist[j]=dist[t]+w;
f[j]=f[t]+cost;
pre[j]=t;
heap.push({dist[j],j});
}
else if(dist[j] == dist[t]+w && f[j] > f[t]+cost)
{
f[j]=f[t]+cost;
pre[j]=t;
}
}
}
}
void dijkstra2(int dist[])
{
memset(dist,0x3f,4*N);
memset(vis,0,sizeof vis);
memset(pre,-1,sizeof pre);
dist[st]=0;
num[st]=1;
priority_queue<PII,vector<PII>,greater<PII>> heap;
heap.push({0,st});
while(heap.size())
{
int t=heap.top().se;
heap.pop();
if(vis[t]) continue;
vis[t]=true;
for(int i=0;i<g[t].size();i++)
{
int j=g[t][i].v,w=g[t][i].len,cost=g[t][i].tim;
if(dist[j] > dist[t] + cost)
{
dist[j]=dist[t]+cost;
num[j]=num[t]+1;
pre[j]=t;
heap.push({dist[j],j});
}
else if(dist[j] == dist[t]+cost && num[j] > num[t]+1)
{
num[j]=num[t]+1;
pre[j]=t;
}
}
}
}
void get_path(int x,vector<int> &path)
{
if(x == -1) return;
get_path(pre[x],path);
path.pb(x);
}
int main()
{
cin>>n>>m;
while(m--)
{
int a,b,t,len,tim;
cin>>a>>b>>t>>len>>tim;
g[a].pb({b,len,tim});
if(t == 0) g[b].pb({a,len,tim});
}
cin>>st>>ed;
dijkstra1(dist1);
get_path(ed,dispath);
dijkstra2(dist2);
get_path(ed,timpath);
if(dispath == timpath)
{
printf("Distance = %d; Time = %d: ",dist1[ed],dist2[ed]);
for(int i=0;i<dispath.size();i++)
if(i) cout<<" -> "<<dispath[i];
else cout<<dispath[i];
cout<<endl;
}
else
{
printf("Distance = %d: ",dist1[ed]);
for(int i=0;i<dispath.size();i++)
if(i) cout<<" -> "<<dispath[i];
else cout<<dispath[i];
cout<<endl;
printf("Time = %d: ",dist2[ed]);
for(int i=0;i<timpath.size();i++)
if(i) cout<<" -> "<<timpath[i];
else cout<<timpath[i];
cout<<endl;
}
//system("pause");
return 0;
}