周游世界 天梯

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;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/88861584
今日推荐