PAT (Advanced Level) Practice 1111 Online Map (30 分)
阿新 • • 發佈:2018-12-07
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=500+5;
struct Edge
{
int v,l,t,next;
}edge[N*N];
struct Length
{
int u,len,mtime;
bool operator<(const Length&p)const
{
if(len!=p.len) return len>p.len;
return mtime>p.mtime;
}
};
struct Time
{
int u,time,mnode;
bool operator<(const Time&p)const
{
if(time!=p.time) return time>p.time;
return mnode>p.mnode;
}
};
int head[N],edgetot,s,t;
int len[N],mtime[N],prel[N];
int time[N],mnode[N],pret[N];
bool vis[ N];
void addEdge(int u,int v,int l,int t)
{
edge[edgetot]={v,l,t,head[u]};
head[u]=edgetot++;
}
void dijsl(int s)
{
memset(len,0x3f,sizeof(len));
memset(mtime,0x3f,sizeof(mtime));
memset(vis,0,sizeof(vis));
priority_queue<Length> q;
q.push({s,0,0});
len[s]=0,mtime[s] =0;
while(!q.empty())
{
Length 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,l=edge[i].l,t=edge[i].t;
if(u.len+l<len[v])
{
len[v]=u.len+l;
mtime[v]=u.mtime+t;
prel[v]=u.u;
q.push({v,len[v],mtime[v]});
}
else if(u.len+l==len[v]&&u.mtime+t<mtime[v])
{
mtime[v]=u.mtime+t;
prel[v]=u.u;
q.push({v,len[v],mtime[v]});
}
}
}
}
void dijst(int s)
{
memset(time,0x3f,sizeof(time));
memset(mnode,0x3f,sizeof(mnode));
memset(vis,0,sizeof(vis));
priority_queue<Time> q;
q.push({s,0,0});
time[s]=0,mnode[s]=0;
while(!q.empty())
{
Time 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,t=edge[i].t;
if(u.time+t<time[v])
{
time[v]=u.time+t;
mnode[v]=u.mnode+1;
pret[v]=u.u;
q.push({v,time[v],mnode[v]});
}
else if(u.time+t==time[v]&&u.mnode+1<mnode[v])
{
mnode[v]=u.mnode+1;
pret[v]=u.u;
q.push({v,time[v],mnode[v]});
}
}
}
}
void print(int* pre,int now)
{
if(now==s) printf("%d",s);
else
{
print(pre,pre[now]);
printf(" -> %d",now);
}
}
int main()
{
memset(head,-1,sizeof(head));
edgetot=0;
int n,m;
scanf("%d%d",&n,&m);
while(m--)
{
int u,v,op,l,t;
scanf("%d%d%d%d%d",&u,&v,&op,&l,&t);
addEdge(u,v,l,t);
if(!op) addEdge(v,u,l,t);
}
scanf("%d%d",&s,&t);
dijsl(s),dijst(s);
int now1=t,now2=t,f=1;
while(now1!=s&&now2!=s)
{
if(now1!=now2){f=0;break;}
now1=prel[now1],now2=pret[now2];
if(now1!=now2){f=0;break;}
}
if(!f)
{
printf("Distance = %d: ",len[t]);
print(prel,t);
puts("");
printf("Time = %d: ",time[t]);
print(pret,t);
puts("");
}
else
{
printf("Distance = %d; Time = %d: ",len[t],time[t]);
print(prel,t);
puts("");
}
return 0;
}