PTA甲级1131 Subway Map(最短路)

#include<bits/stdc++.h>
using namespace std;

#define pii pair<int,int>
const int N=10010,M=1000010;

int h[N],e[M],ne[M],w[M],line[M];
string s[N];
int dist[N],st[N],pre[N],cnt[N],idx;
int n,m,ss,ee;

void add(int a,int b,int c,int d)
{
    e[idx]=b,w[idx]=c,line[idx]=d,ne[idx]=h[a],h[a]=idx++;
}

string to_s(int x)
{
    string s=to_string(x),ss="";
    for(int i=0;i<4-s.size();i++)ss+="0";
    return ss+s;
}
void dijk(int ss,int ee)
{
    memset(dist,0x3f,sizeof dist);
    memset(st,0,sizeof st);
    memset(cnt,0x3f,sizeof cnt);
    dist[ss]=cnt[ss]=0;

    priority_queue<pii,vector<pii>,greater<pii>>q;
    q.push({0,ss});

    while(q.size())
    {
        auto t=q.top();
        q.pop();

        int ver=t.second;
        if(ver==ee)break;
        for(int i=h[ver];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[ver]+w[i])
            {
                cnt[j]=cnt[ver];
                dist[j]=dist[ver]+w[i];
                pre[j]=ver;
                q.push({dist[j],j});
               // cout<<to_s(j)<<"++"<<endl;
                s[j]="Take Line#"+to_string(line[i])+" from "+to_s(ver)+" to "+to_s(j)+".";
            }else if(dist[j]==dist[ver]+w[i])
            {
                if(cnt[j]>cnt[ver]+1)
                {
                    cnt[j]=cnt[ver]+1;
                    pre[j]=ver;
                    s[j]="Take Line#"+to_string(line[i])+" from "+to_s(ver)+" to "+to_s(j)+".";
                }
            }
        }
    }
}

void print(int x)
{
    if(x!=ss)print(pre[x]);
    else return;
    cout<<s[x]<<endl;
}
int main()
{
    cin>>n;
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    memset(h,-1,sizeof h);
    for(int i=1;i<=n;i++)
    {
        vector<int>g;
        int x;
        cin>>x;
        for(int j=0;j<x;j++)
        {
            int y;
            cin>>y;
            g.push_back(y);
        }
        for(int j=0;j<x;j++)
        {
            for(int k=0;k<j;k++)
            {
                int len=0;
                if(g[0]!=g[x-1])len=j-k;
                else len=min(j-k,x-1-j+k);
              //  cout<<g[j]<<" "<<g[k]<<" "<<len<<endl;
                add(g[j],g[k],len,i);
                add(g[k],g[j],len,i);
            }
        }
    }
    int k;
    cin>>k;
    while(k--)
    {
        cin>>ss>>ee;
        dijk(ss,ee);
        cout<<dist[ee]<<endl;
        print(ee);
    }
}

该题是最短路算法,其中建图的时候,因为题目中说可能会有环,但是不会有自环,如果没有环,那一条地铁线之间的距离就是两个下标之差,如果有环,那就要考虑取最近的距离最为两点之间的距离, 最后的答案还要输出路线,我们可以在更新前驱节点的同时更新路线,最后就和以前的题一眼,直接递归输出即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值