​https://pintia.cn/problem-sets/994805046380707840/problems/994805048482054144​

对于每个公司的线路 将线路上的点两两都连一条边 权值即为两站距离 这样边权和作为第一关键字 边数和作为第二关键字 跑一遍dijkstra并记录路径即可

水题出的太慢 最后竟然没写完 一定要稳住心态啊。。

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N=0x3f3f3f3f;
const int maxk=1e2+10;
const int maxn=1e4+10;
const int maxm=1e6+10;

struct node1
{
int v,w,id,next;
};

struct node2
{
bool friend operator < (node2 n1,node2 n2){
if(n1.val1==n2.val1) return n1.val2>n2.val2;
else return n1.val1>n2.val1;
}
int id,val1,val2;
};

node1 edge[maxm];
priority_queue <node2> que;
int first[maxn],dis1[maxn],dis2[maxn],book[maxn],pre1[maxn],pre2[maxn];
int n,num;

void addedge(int u,int v,int w,int id)
{
edge[num].v=v;
edge[num].w=w;
edge[num].id=id;
edge[num].next=first[u];
first[u]=num++;
}

int dijkstra(int s,int e)
{
node2 cur,tmp;
int i,u,v,w,id;
while(!que.empty()) que.pop();
memset(dis1,0x3f,sizeof(dis1));
memset(dis2,0x3f,sizeof(dis2));
memset(book,0,sizeof(book));
dis1[s]=0,dis2[s]=0,pre1[s]=-1,pre2[s]=-1;
tmp.id=s,tmp.val1=0,tmp.val2=0;
que.push(tmp);
while(!que.empty()){
cur=que.top();
que.pop();
u=cur.id;
if(book[u]) continue;
book[u]=1;
for(i=first[u];i!=-1;i=edge[i].next){
v=edge[i].v,w=edge[i].w,id=edge[i].id;
if(!book[v]){
if(dis1[v]>dis1[u]+w){
dis1[v]=dis1[u]+w,dis2[v]=dis2[u]+1,pre1[v]=u,pre2[v]=id;
tmp.id=v,tmp.val1=dis1[v],tmp.val2=dis2[v];
que.push(tmp);
}
else if(dis1[v]==dis1[u]+w&&dis2[v]>dis2[u]+1){
dis2[v]=dis2[u]+1,pre1[v]=u,pre2[v]=id;
tmp.id=v,tmp.val1=dis1[v],tmp.val2=dis2[v];
que.push(tmp);
}
}
}
}
return dis1[e];
}

void dfs(int cur)
{
//Go by the line of company #3 from 3011 to 3013.
if(pre1[cur]==-1) return;
dfs(pre1[cur]);
printf("Go by the line of company #%d from %04d to %04d.\n",pre2[cur],pre1[cur],cur);
}

int main()
{
int ary[maxk];
int t,id,k,i,j,q,s,e,res;
memset(first,-1,sizeof(first));
num=0;
scanf("%d",&t);
for(id=1;id<=t;id++){
scanf("%d",&k);
for(i=1;i<=k;i++){
scanf("%d",&ary[i]);
}
for(i=1;i<=k;i++){
for(j=i+1;j<=k;j++){
if(ary[i]!=ary[j]){
addedge(ary[i],ary[j],j-i,id);
addedge(ary[j],ary[i],j-i,id);
}
}
}
}
scanf("%d",&q);
while(q--){
scanf("%d%d",&s,&e);
res=dijkstra(s,e);
if(res!=N){
printf("%d\n",res);
dfs(e);
}
else{
printf("Sorry, no line is available.\n");
}
}
return 0;
}