zoukankan      html  css  js  c++  java
  • PAT 1131. Subway Map (30)

    最短路。

    记录一下到某个点,最后是哪辆车乘到的最短距离、换乘次数以及从哪个位置推过来的,可以开$map$记录一下。

    #include<map>
    #include<set>
    #include<ctime>
    #include<cmath>
    #include<queue>
    #include<string>
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
    
    int n,A,B;
    
    map<int,int>dis;
    map<int,int>num;
    map<int,int>pre;
    map<int,bool>f;
    int a[200];
    vector<int>g[10010];
    
    struct X
    {
        int x,y,z;
    }s[1000010];
    int sz;
    
    int xl[1000010],p;
    
    void add(int x,int y,int z)
    {
        s[sz].x=x; s[sz].y=y; s[sz].z=z;
        g[x].push_back(sz); sz++;
    }
    
    void SPFA()
    {
        dis.clear(); num.clear(); pre.clear(); f.clear();
        queue<int>Q;
    
        for(int j=1;j<=n;j++)
        {
            dis[A*1000+j]=1;
            num[A*1000+j]=1;
            Q.push(A*1000+j); f[A*1000+j]=1;
        }
    
        while(!Q.empty())
        {
            int h=Q.front(); Q.pop(); f[h]=0;
            int dian =h/1000 ,ban = h%1000;
            for(int i=0;i<g[dian].size();i++)
            {
                int id = g[dian][i];
                int ha = s[id].y*1000+s[id].z;
    
                if(dis[ha]==0)
                {
                    dis[ha] = dis[h]+1;
                    if(s[id].z==ban) num[ha] = num[h];
                    else num[ha] = num[h]+1;
                    pre[ha] = h;
                    if(f[ha]==0) { f[ha]=1; Q.push(ha); }
                }
                else
                {
                    if(dis[h]+1<dis[ha])
                    {
                        dis[ha] = dis[h]+1;
                        if(s[id].z==ban) num[ha] = num[h];
                        else num[ha] = num[h]+1;
                        pre[ha] = h;
                        if(f[ha]==0) { f[ha]=1; Q.push(ha); }
                    }
    
                    else if(dis[h]+1==dis[ha])
                    {
                        int tmp;
                        if(s[id].z==ban) tmp = num[h];
                        else tmp = num[h]+1;
    
                        if(tmp<num[ha])
                        {
                            dis[ha] = dis[h]+1;
                            if(s[id].z==ban) num[ha] = num[h];
                            else num[ha] = num[h]+1;
                            pre[ha] = h;
                            if(f[ha]==0) { f[ha]=1; Q.push(ha); }
                        }
                    }
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int m; scanf("%d",&m);
            for(int j=1;j<=m;j++) scanf("%d",&a[j]);
            for(int j=1;j<=m;j++)
            {
                if(j-1>=1) add(a[j],a[j-1],i);
                if(j+1<=m) add(a[j],a[j+1],i);
            }
        }
    
        int Q; scanf("%d",&Q);
        while(Q--)
        {
            scanf("%d%d",&A,&B);
            SPFA();
    
            int ans=0x7FFFFFFF;
            for(int i=1;i<=n;i++)
            {
                if(dis[B*1000+i]==0) continue;
                ans=min(ans,dis[B*1000+i]-1);
            }
    
            printf("%d
    ",ans);
    
            int MinTra=0x7FFFFFFF,idx;
            for(int i=1;i<=n;i++)
            {
                if(dis[B*1000+i]-1!=ans) continue;
                if(num[B*1000+i]<MinTra)
                {
                    MinTra=num[B*1000+i];
                    idx = B*1000+i;
                }
            }
    
            stack<int>st; int now =idx;
            while(1)
            {
                if(now==0) break;
                st.push(now);
                now = pre[now];
            }
    
            p=0;
            while(!st.empty()) { xl[p++]=st.top(); st.pop(); }
    
            int len=p; xl[len]=0;
    
    
            p=0;
            while(1)
            {
                if(xl[p]%1000==xl[0]%1000) p++;
                else break;
            }
            p--;
    
            printf("Take Line#%d from %04d to %04d.
    ",xl[0]%1000,xl[0]/1000,xl[p]/1000);
    
            int pre = xl[p]/1000;
            while(1)
            {
                p++; if(p>len-1) break;
                int tmp = p;
                while(1)
                {
                    if(xl[tmp]%1000==xl[p]%1000) p++;
                    else break;
                }
                p--;
                printf("Take Line#%d from %04d to %04d.
    ",xl[p]%1000,pre,xl[p]/1000);
                pre=xl[p]/1000;
            }
    
        }
        return 0;
    }
  • 相关阅读:
    洛谷 P1194 飞扬的小鸟 题解
    洛谷 P1197 星球大战 题解
    洛谷 P1879 玉米田Corn Fields 题解
    洛谷 P2796 Facer的程序 题解
    洛谷 P2398 GCD SUM 题解
    洛谷 P2051 中国象棋 题解
    洛谷 P1472 奶牛家谱 Cow Pedigrees 题解
    洛谷 P1004 方格取数 题解
    洛谷 P2331 最大子矩阵 题解
    洛谷 P1073 最优贸易 题解
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6603550.html
Copyright © 2011-2022 走看看