zoukankan      html  css  js  c++  java
  • 天梯赛 周游世界

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

    就是求从s到t在满足2个条件下的最短路

    条件1:经过边数最少

    条件2:在条件1的基础上换乘次数最少

    条件1好满足,直接bfs一遍,记录边数即可

    条件2,因为题目说换乘点不会超过5条边,所以在每个换乘点都记录一下在最短路和换乘次数最少的前提下,该点是由哪几种边到达的

    输出方案的时候

    从终点开始往前走

    假设一条从u到v的边

    首先要满足到u的最短路比到v的最短路少1

    对于条件2,如果u和v的最少换乘次数一样,那么在到u的前面说的记录的边里,一定有一条和当前边同一类型的边

    如果u比v的换乘次数少一次,那么u就是到v之前经过的点

    #include<cstdio>
    #include<queue>
    #include<cstring>
    
    using namespace std;
    
    #define N 100001
    
    int front[N],to[N<<1],nxt[N<<1],tot,col[N<<1];
    
    int s,d; 
    
    int dis[N],chan[N],wh[N][6];
    bool in[N];
    
    int ansp[N],ansc[N];
     
    void add(int u,int v,int w)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; col[tot]=w;
    } 
    
    void solve()
    {
        for(int i=0;i<N;++i) 
        {
            dis[i]=1e9;
            chan[i]=1e9;
            wh[i][0]=0;
        }
        memset(in,false,sizeof(in));
        queue<int>q;
        dis[s]=chan[s]=0; 
        q.push(s);
        in[s]=true;
        int now,t,tmp;
        while(!q.empty())
        {
            now=q.front();
            q.pop();
            in[now]=false;
            for(int i=front[now];i;i=nxt[i])
            {
                t=to[i];
                if(dis[t]>=dis[now]+1)
                {
                    if(dis[t]>dis[now]+1)
                    {
                        dis[t]=dis[now]+1;
                        tmp=chan[now];
                        int j;
                        for(j=1;j<=wh[now][0];++j)
                            if(col[i]==wh[now][j]) break;
                        if(j>wh[now][0]) tmp++;
                        wh[t][0]=1;
                        wh[t][1]=col[i];
                        chan[t]=tmp;
                    }
                    else
                    {
                        tmp=chan[now];
                        int j;
                        for(j=1;j<=wh[now][0];++j)
                            if(col[i]==wh[now][j]) break;
                        if(j>wh[now][0]) tmp++;
                        if(tmp<chan[t])
                        {
                            chan[t]=tmp;
                            wh[t][0]=1;
                            wh[t][1]=col[i];
                        }
                        else if(tmp==chan[t])
                        {
                            bool ii=false;
                            for(int k=1;k<=wh[t][0] && !ii;++k)
                                if(wh[t][k]==col[i]) ii=true;
                            if(!ii) 
                            {
                                wh[t][0]++;
                                wh[t][wh[t][0]]=col[i];
                            }
                        }
                        else continue; 
                    }
                }
                else continue;
                if(!in[t] && t!=d) 
                {
                    q.push(t);
                    in[t]=true;
                }
            }
        }
        if(dis[d]==1e9) printf("Sorry, no line is available.
    ");
        else
        {
            printf("%d
    ",dis[d]);
            now=d;
            int sum=0;
            bool flag;
            ansp[++sum]=d;
            while(now!=s)
            {
                for(int i=front[now];i;i=nxt[i])
                    if(dis[to[i]]==dis[now]-1)
                    {
                        if(chan[to[i]]==chan[now]) 
                        {
                            flag=false;
                            for(int j=1;j<=wh[to[i]][0] && !flag;++j)
                                if(wh[to[i]][j]==col[i]) flag=true;
                            if(flag)
                            {
                                now=to[i];
                                break;
                            }
                        }
                        else if(chan[to[i]]==chan[now]-1)
                        {
                            ansc[sum]=col[i];
                            ansp[++sum]=to[i];
                            now=to[i];
                            break;
                        }
                    }
            }
            for(int i=sum-1;i;--i)
                printf("Go by the line of company #%d from %04d to %04d.
    ",ansc[i],ansp[i+1],ansp[i]);
        }
    }
    
    int main()
    {
        int T,m,x,last;
        scanf("%d",&T);
        for(int i=1;i<=T;++i)
        {
            scanf("%d",&m);
            scanf("%d",&last);
            while(--m)
            {
                scanf("%d",&x);
                add(last,x,i);
                add(x,last,i);
                last=x; 
            }
        }
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&s,&d);
            solve();
        }
    }
  • 相关阅读:
    Java生鲜电商平台-物流配送的设计与架构
    五分钟学Java:如何学习Java面试必考的网络编程
    五分钟学Java:如何学习Java面试必考的网络编程
    Java原来还可以这么学:如何搞定面试中必考的集合类
    五分钟学Java:如何学习Java面试必考的JVM虚拟机
    先搞清楚这些问题,简历上再写你熟悉Java!
    MySql/Oracle和SQL Server的分页查
    Java面试题之int和Integer的区别
    Java基本数据类型转换
    Shiro-Subject 分析
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/13766957.html
Copyright © 2011-2022 走看看